1*b7893ccfSSadaf Ebrahimi /* Copyright (c) 2015-2019 The Khronos Group Inc.
2*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 Valve Corporation
3*b7893ccfSSadaf Ebrahimi * Copyright (c) 2015-2019 LunarG, Inc.
4*b7893ccfSSadaf Ebrahimi * Copyright (C) 2015-2019 Google Inc.
5*b7893ccfSSadaf Ebrahimi *
6*b7893ccfSSadaf Ebrahimi * Licensed under the Apache License, Version 2.0 (the "License");
7*b7893ccfSSadaf Ebrahimi * you may not use this file except in compliance with the License.
8*b7893ccfSSadaf Ebrahimi * You may obtain a copy of the License at
9*b7893ccfSSadaf Ebrahimi *
10*b7893ccfSSadaf Ebrahimi * http://www.apache.org/licenses/LICENSE-2.0
11*b7893ccfSSadaf Ebrahimi *
12*b7893ccfSSadaf Ebrahimi * Unless required by applicable law or agreed to in writing, software
13*b7893ccfSSadaf Ebrahimi * distributed under the License is distributed on an "AS IS" BASIS,
14*b7893ccfSSadaf Ebrahimi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*b7893ccfSSadaf Ebrahimi * See the License for the specific language governing permissions and
16*b7893ccfSSadaf Ebrahimi * limitations under the License.
17*b7893ccfSSadaf Ebrahimi *
18*b7893ccfSSadaf Ebrahimi * Author: Mark Lobodzinski <[email protected]>
19*b7893ccfSSadaf Ebrahimi * Author: John Zulauf <[email protected]>
20*b7893ccfSSadaf Ebrahimi */
21*b7893ccfSSadaf Ebrahimi
22*b7893ccfSSadaf Ebrahimi #define NOMINMAX
23*b7893ccfSSadaf Ebrahimi
24*b7893ccfSSadaf Ebrahimi #include <math.h>
25*b7893ccfSSadaf Ebrahimi
26*b7893ccfSSadaf Ebrahimi #include "chassis.h"
27*b7893ccfSSadaf Ebrahimi #include "stateless_validation.h"
28*b7893ccfSSadaf Ebrahimi #include "layer_chassis_dispatch.h"
29*b7893ccfSSadaf Ebrahimi
30*b7893ccfSSadaf Ebrahimi static const int MaxParamCheckerStringLength = 256;
31*b7893ccfSSadaf Ebrahimi
32*b7893ccfSSadaf Ebrahimi template <typename T>
in_inclusive_range(const T & value,const T & min,const T & max)33*b7893ccfSSadaf Ebrahimi inline bool in_inclusive_range(const T &value, const T &min, const T &max) {
34*b7893ccfSSadaf Ebrahimi // Using only < for generality and || for early abort
35*b7893ccfSSadaf Ebrahimi return !((value < min) || (max < value));
36*b7893ccfSSadaf Ebrahimi }
37*b7893ccfSSadaf Ebrahimi
validate_string(const char * apiName,const ParameterName & stringName,const std::string & vuid,const char * validateString)38*b7893ccfSSadaf Ebrahimi bool StatelessValidation::validate_string(const char *apiName, const ParameterName &stringName, const std::string &vuid,
39*b7893ccfSSadaf Ebrahimi const char *validateString) {
40*b7893ccfSSadaf Ebrahimi bool skip = false;
41*b7893ccfSSadaf Ebrahimi
42*b7893ccfSSadaf Ebrahimi VkStringErrorFlags result = vk_string_validate(MaxParamCheckerStringLength, validateString);
43*b7893ccfSSadaf Ebrahimi
44*b7893ccfSSadaf Ebrahimi if (result == VK_STRING_ERROR_NONE) {
45*b7893ccfSSadaf Ebrahimi return skip;
46*b7893ccfSSadaf Ebrahimi } else if (result & VK_STRING_ERROR_LENGTH) {
47*b7893ccfSSadaf Ebrahimi skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
48*b7893ccfSSadaf Ebrahimi "%s: string %s exceeds max length %d", apiName, stringName.get_name().c_str(), MaxParamCheckerStringLength);
49*b7893ccfSSadaf Ebrahimi } else if (result & VK_STRING_ERROR_BAD_DATA) {
50*b7893ccfSSadaf Ebrahimi skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
51*b7893ccfSSadaf Ebrahimi "%s: string %s contains invalid characters or is badly formed", apiName, stringName.get_name().c_str());
52*b7893ccfSSadaf Ebrahimi }
53*b7893ccfSSadaf Ebrahimi return skip;
54*b7893ccfSSadaf Ebrahimi }
55*b7893ccfSSadaf Ebrahimi
validate_api_version(uint32_t api_version,uint32_t effective_api_version)56*b7893ccfSSadaf Ebrahimi bool StatelessValidation::validate_api_version(uint32_t api_version, uint32_t effective_api_version) {
57*b7893ccfSSadaf Ebrahimi bool skip = false;
58*b7893ccfSSadaf Ebrahimi uint32_t api_version_nopatch = VK_MAKE_VERSION(VK_VERSION_MAJOR(api_version), VK_VERSION_MINOR(api_version), 0);
59*b7893ccfSSadaf Ebrahimi if (api_version_nopatch != effective_api_version) {
60*b7893ccfSSadaf Ebrahimi if (api_version_nopatch < VK_API_VERSION_1_0) {
61*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
62*b7893ccfSSadaf Ebrahimi HandleToUint64(instance), kVUIDUndefined,
63*b7893ccfSSadaf Ebrahimi "Invalid CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
64*b7893ccfSSadaf Ebrahimi "Using VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
65*b7893ccfSSadaf Ebrahimi api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
66*b7893ccfSSadaf Ebrahimi } else {
67*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
68*b7893ccfSSadaf Ebrahimi HandleToUint64(instance), kVUIDUndefined,
69*b7893ccfSSadaf Ebrahimi "Unrecognized CreateInstance->pCreateInfo->pApplicationInfo.apiVersion number (0x%08x). "
70*b7893ccfSSadaf Ebrahimi "Assuming VK_API_VERSION_%" PRIu32 "_%" PRIu32 ".",
71*b7893ccfSSadaf Ebrahimi api_version, VK_VERSION_MAJOR(effective_api_version), VK_VERSION_MINOR(effective_api_version));
72*b7893ccfSSadaf Ebrahimi }
73*b7893ccfSSadaf Ebrahimi }
74*b7893ccfSSadaf Ebrahimi return skip;
75*b7893ccfSSadaf Ebrahimi }
76*b7893ccfSSadaf Ebrahimi
validate_instance_extensions(const VkInstanceCreateInfo * pCreateInfo)77*b7893ccfSSadaf Ebrahimi bool StatelessValidation::validate_instance_extensions(const VkInstanceCreateInfo *pCreateInfo) {
78*b7893ccfSSadaf Ebrahimi bool skip = false;
79*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
80*b7893ccfSSadaf Ebrahimi skip |= validate_extension_reqs(instance_extensions, "VUID-vkCreateInstance-ppEnabledExtensionNames-01388", "instance",
81*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames[i]);
82*b7893ccfSSadaf Ebrahimi }
83*b7893ccfSSadaf Ebrahimi
84*b7893ccfSSadaf Ebrahimi return skip;
85*b7893ccfSSadaf Ebrahimi }
86*b7893ccfSSadaf Ebrahimi
87*b7893ccfSSadaf Ebrahimi template <typename ExtensionState>
extension_state_by_name(const ExtensionState & extensions,const char * extension_name)88*b7893ccfSSadaf Ebrahimi bool extension_state_by_name(const ExtensionState &extensions, const char *extension_name) {
89*b7893ccfSSadaf Ebrahimi if (!extension_name) return false; // null strings specify nothing
90*b7893ccfSSadaf Ebrahimi auto info = ExtensionState::get_info(extension_name);
91*b7893ccfSSadaf Ebrahimi bool state = info.state ? extensions.*(info.state) : false; // unknown extensions can't be enabled in extension struct
92*b7893ccfSSadaf Ebrahimi return state;
93*b7893ccfSSadaf Ebrahimi }
94*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)95*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
96*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
97*b7893ccfSSadaf Ebrahimi bool skip = false;
98*b7893ccfSSadaf Ebrahimi // Note: From the spec--
99*b7893ccfSSadaf Ebrahimi // Providing a NULL VkInstanceCreateInfo::pApplicationInfo or providing an apiVersion of 0 is equivalent to providing
100*b7893ccfSSadaf Ebrahimi // an apiVersion of VK_MAKE_VERSION(1, 0, 0). (a.k.a. VK_API_VERSION_1_0)
101*b7893ccfSSadaf Ebrahimi uint32_t local_api_version = (pCreateInfo->pApplicationInfo && pCreateInfo->pApplicationInfo->apiVersion)
102*b7893ccfSSadaf Ebrahimi ? pCreateInfo->pApplicationInfo->apiVersion
103*b7893ccfSSadaf Ebrahimi : VK_API_VERSION_1_0;
104*b7893ccfSSadaf Ebrahimi skip |= validate_api_version(local_api_version, api_version);
105*b7893ccfSSadaf Ebrahimi skip |= validate_instance_extensions(pCreateInfo);
106*b7893ccfSSadaf Ebrahimi return skip;
107*b7893ccfSSadaf Ebrahimi }
108*b7893ccfSSadaf Ebrahimi
PostCallRecordCreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance,VkResult result)109*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordCreateInstance(const VkInstanceCreateInfo *pCreateInfo,
110*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkInstance *pInstance,
111*b7893ccfSSadaf Ebrahimi VkResult result) {
112*b7893ccfSSadaf Ebrahimi auto instance_data = GetLayerDataPtr(get_dispatch_key(*pInstance), layer_data_map);
113*b7893ccfSSadaf Ebrahimi // Copy extension data into local object
114*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) return;
115*b7893ccfSSadaf Ebrahimi this->instance_extensions = instance_data->instance_extensions;
116*b7893ccfSSadaf Ebrahimi }
117*b7893ccfSSadaf Ebrahimi
PostCallRecordQueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * pPresentInfo,VkResult result)118*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo, VkResult result) {
119*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
120*b7893ccfSSadaf Ebrahimi auto swapchains_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
121*b7893ccfSSadaf Ebrahimi if (swapchains_result == VK_SUBOPTIMAL_KHR) {
122*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
123*b7893ccfSSadaf Ebrahimi HandleToUint64(pPresentInfo->pSwapchains[i]), kVUID_PVPerfWarn_SuboptimalSwapchain,
124*b7893ccfSSadaf Ebrahimi "vkQueuePresentKHR: %s :VK_SUBOPTIMAL_KHR was returned. VK_SUBOPTIMAL_KHR - Presentation will still succeed, "
125*b7893ccfSSadaf Ebrahimi "subject to the window resize behavior, but the swapchain is no longer configured optimally for the surface it "
126*b7893ccfSSadaf Ebrahimi "targets. Applications should query updated surface information and recreate their swapchain at the next "
127*b7893ccfSSadaf Ebrahimi "convenient opportunity.",
128*b7893ccfSSadaf Ebrahimi report_data->FormatHandle(pPresentInfo->pSwapchains[i]).c_str());
129*b7893ccfSSadaf Ebrahimi }
130*b7893ccfSSadaf Ebrahimi }
131*b7893ccfSSadaf Ebrahimi }
132*b7893ccfSSadaf Ebrahimi
PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice,VkResult result)133*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
134*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkDevice *pDevice, VkResult result) {
135*b7893ccfSSadaf Ebrahimi auto device_data = GetLayerDataPtr(get_dispatch_key(*pDevice), layer_data_map);
136*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) return;
137*b7893ccfSSadaf Ebrahimi ValidationObject *validation_data = GetValidationObject(device_data->object_dispatch, LayerObjectTypeParameterValidation);
138*b7893ccfSSadaf Ebrahimi StatelessValidation *stateless_validation = static_cast<StatelessValidation *>(validation_data);
139*b7893ccfSSadaf Ebrahimi
140*b7893ccfSSadaf Ebrahimi // Parmeter validation also uses extension data
141*b7893ccfSSadaf Ebrahimi stateless_validation->device_extensions = this->device_extensions;
142*b7893ccfSSadaf Ebrahimi
143*b7893ccfSSadaf Ebrahimi VkPhysicalDeviceProperties device_properties = {};
144*b7893ccfSSadaf Ebrahimi // Need to get instance and do a getlayerdata call...
145*b7893ccfSSadaf Ebrahimi DispatchGetPhysicalDeviceProperties(physicalDevice, &device_properties);
146*b7893ccfSSadaf Ebrahimi memcpy(&stateless_validation->device_limits, &device_properties.limits, sizeof(VkPhysicalDeviceLimits));
147*b7893ccfSSadaf Ebrahimi
148*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_nv_shading_rate_image) {
149*b7893ccfSSadaf Ebrahimi // Get the needed shading rate image limits
150*b7893ccfSSadaf Ebrahimi auto shading_rate_image_props = lvl_init_struct<VkPhysicalDeviceShadingRateImagePropertiesNV>();
151*b7893ccfSSadaf Ebrahimi auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&shading_rate_image_props);
152*b7893ccfSSadaf Ebrahimi DispatchGetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
153*b7893ccfSSadaf Ebrahimi phys_dev_ext_props.shading_rate_image_props = shading_rate_image_props;
154*b7893ccfSSadaf Ebrahimi }
155*b7893ccfSSadaf Ebrahimi
156*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_nv_mesh_shader) {
157*b7893ccfSSadaf Ebrahimi // Get the needed mesh shader limits
158*b7893ccfSSadaf Ebrahimi auto mesh_shader_props = lvl_init_struct<VkPhysicalDeviceMeshShaderPropertiesNV>();
159*b7893ccfSSadaf Ebrahimi auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&mesh_shader_props);
160*b7893ccfSSadaf Ebrahimi DispatchGetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
161*b7893ccfSSadaf Ebrahimi phys_dev_ext_props.mesh_shader_props = mesh_shader_props;
162*b7893ccfSSadaf Ebrahimi }
163*b7893ccfSSadaf Ebrahimi
164*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_nv_ray_tracing) {
165*b7893ccfSSadaf Ebrahimi // Get the needed ray tracing limits
166*b7893ccfSSadaf Ebrahimi auto ray_tracing_props = lvl_init_struct<VkPhysicalDeviceRayTracingPropertiesNV>();
167*b7893ccfSSadaf Ebrahimi auto prop2 = lvl_init_struct<VkPhysicalDeviceProperties2KHR>(&ray_tracing_props);
168*b7893ccfSSadaf Ebrahimi DispatchGetPhysicalDeviceProperties2KHR(physicalDevice, &prop2);
169*b7893ccfSSadaf Ebrahimi phys_dev_ext_props.ray_tracing_props = ray_tracing_props;
170*b7893ccfSSadaf Ebrahimi }
171*b7893ccfSSadaf Ebrahimi
172*b7893ccfSSadaf Ebrahimi stateless_validation->phys_dev_ext_props = this->phys_dev_ext_props;
173*b7893ccfSSadaf Ebrahimi
174*b7893ccfSSadaf Ebrahimi // Save app-enabled features in this device's validation object
175*b7893ccfSSadaf Ebrahimi // The enabled features can come from either pEnabledFeatures, or from the pNext chain
176*b7893ccfSSadaf Ebrahimi const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
177*b7893ccfSSadaf Ebrahimi safe_VkPhysicalDeviceFeatures2 tmp_features2_state;
178*b7893ccfSSadaf Ebrahimi tmp_features2_state.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
179*b7893ccfSSadaf Ebrahimi if (features2) {
180*b7893ccfSSadaf Ebrahimi tmp_features2_state.features = features2->features;
181*b7893ccfSSadaf Ebrahimi } else if (pCreateInfo->pEnabledFeatures) {
182*b7893ccfSSadaf Ebrahimi tmp_features2_state.features = *pCreateInfo->pEnabledFeatures;
183*b7893ccfSSadaf Ebrahimi } else {
184*b7893ccfSSadaf Ebrahimi tmp_features2_state.features = {};
185*b7893ccfSSadaf Ebrahimi }
186*b7893ccfSSadaf Ebrahimi // Use pCreateInfo->pNext to get full chain
187*b7893ccfSSadaf Ebrahimi tmp_features2_state.pNext = SafePnextCopy(pCreateInfo->pNext);
188*b7893ccfSSadaf Ebrahimi stateless_validation->physical_device_features2 = tmp_features2_state;
189*b7893ccfSSadaf Ebrahimi }
190*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)191*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo *pCreateInfo,
192*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
193*b7893ccfSSadaf Ebrahimi bool skip = false;
194*b7893ccfSSadaf Ebrahimi bool maint1 = false;
195*b7893ccfSSadaf Ebrahimi bool negative_viewport = false;
196*b7893ccfSSadaf Ebrahimi
197*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->enabledLayerCount > 0) && (pCreateInfo->ppEnabledLayerNames != NULL)) {
198*b7893ccfSSadaf Ebrahimi for (size_t i = 0; i < pCreateInfo->enabledLayerCount; i++) {
199*b7893ccfSSadaf Ebrahimi skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledLayerNames",
200*b7893ccfSSadaf Ebrahimi "VUID-VkDeviceCreateInfo-ppEnabledLayerNames-parameter", pCreateInfo->ppEnabledLayerNames[i]);
201*b7893ccfSSadaf Ebrahimi }
202*b7893ccfSSadaf Ebrahimi }
203*b7893ccfSSadaf Ebrahimi
204*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->enabledExtensionCount > 0) && (pCreateInfo->ppEnabledExtensionNames != NULL)) {
205*b7893ccfSSadaf Ebrahimi maint1 = extension_state_by_name(device_extensions, VK_KHR_MAINTENANCE1_EXTENSION_NAME);
206*b7893ccfSSadaf Ebrahimi negative_viewport = extension_state_by_name(device_extensions, VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME);
207*b7893ccfSSadaf Ebrahimi
208*b7893ccfSSadaf Ebrahimi for (size_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
209*b7893ccfSSadaf Ebrahimi skip |= validate_string("vkCreateDevice", "pCreateInfo->ppEnabledExtensionNames",
210*b7893ccfSSadaf Ebrahimi "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-parameter",
211*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames[i]);
212*b7893ccfSSadaf Ebrahimi skip |= validate_extension_reqs(device_extensions, "VUID-vkCreateDevice-ppEnabledExtensionNames-01387", "device",
213*b7893ccfSSadaf Ebrahimi pCreateInfo->ppEnabledExtensionNames[i]);
214*b7893ccfSSadaf Ebrahimi }
215*b7893ccfSSadaf Ebrahimi }
216*b7893ccfSSadaf Ebrahimi
217*b7893ccfSSadaf Ebrahimi if (maint1 && negative_viewport) {
218*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
219*b7893ccfSSadaf Ebrahimi "VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-00374",
220*b7893ccfSSadaf Ebrahimi "VkDeviceCreateInfo->ppEnabledExtensionNames must not simultaneously include VK_KHR_maintenance1 and "
221*b7893ccfSSadaf Ebrahimi "VK_AMD_negative_viewport_height.");
222*b7893ccfSSadaf Ebrahimi }
223*b7893ccfSSadaf Ebrahimi
224*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pNext != NULL && pCreateInfo->pEnabledFeatures) {
225*b7893ccfSSadaf Ebrahimi // Check for get_physical_device_properties2 struct
226*b7893ccfSSadaf Ebrahimi const auto *features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2KHR>(pCreateInfo->pNext);
227*b7893ccfSSadaf Ebrahimi if (features2) {
228*b7893ccfSSadaf Ebrahimi // Cannot include VkPhysicalDeviceFeatures2KHR and have non-null pEnabledFeatures
229*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
230*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidUsage,
231*b7893ccfSSadaf Ebrahimi "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2KHR struct when "
232*b7893ccfSSadaf Ebrahimi "pCreateInfo->pEnabledFeatures is non-NULL.");
233*b7893ccfSSadaf Ebrahimi }
234*b7893ccfSSadaf Ebrahimi }
235*b7893ccfSSadaf Ebrahimi
236*b7893ccfSSadaf Ebrahimi auto features2 = lvl_find_in_chain<VkPhysicalDeviceFeatures2>(pCreateInfo->pNext);
237*b7893ccfSSadaf Ebrahimi if (features2) {
238*b7893ccfSSadaf Ebrahimi if (!instance_extensions.vk_khr_get_physical_device_properties_2) {
239*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
240*b7893ccfSSadaf Ebrahimi kVUID_PVError_ExtensionNotEnabled,
241*b7893ccfSSadaf Ebrahimi "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceFeatures2 struct, "
242*b7893ccfSSadaf Ebrahimi "VK_KHR_get_physical_device_properties2 must be enabled when it creates an instance.");
243*b7893ccfSSadaf Ebrahimi }
244*b7893ccfSSadaf Ebrahimi }
245*b7893ccfSSadaf Ebrahimi
246*b7893ccfSSadaf Ebrahimi auto vertex_attribute_divisor_features =
247*b7893ccfSSadaf Ebrahimi lvl_find_in_chain<VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT>(pCreateInfo->pNext);
248*b7893ccfSSadaf Ebrahimi if (vertex_attribute_divisor_features) {
249*b7893ccfSSadaf Ebrahimi bool extension_found = false;
250*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; ++i) {
251*b7893ccfSSadaf Ebrahimi if (0 == strncmp(pCreateInfo->ppEnabledExtensionNames[i], VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME,
252*b7893ccfSSadaf Ebrahimi VK_MAX_EXTENSION_NAME_SIZE)) {
253*b7893ccfSSadaf Ebrahimi extension_found = true;
254*b7893ccfSSadaf Ebrahimi break;
255*b7893ccfSSadaf Ebrahimi }
256*b7893ccfSSadaf Ebrahimi }
257*b7893ccfSSadaf Ebrahimi if (!extension_found) {
258*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
259*b7893ccfSSadaf Ebrahimi kVUID_PVError_ExtensionNotEnabled,
260*b7893ccfSSadaf Ebrahimi "VkDeviceCreateInfo->pNext includes a VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT "
261*b7893ccfSSadaf Ebrahimi "struct, VK_EXT_vertex_attribute_divisor must be enabled when it creates a device.");
262*b7893ccfSSadaf Ebrahimi }
263*b7893ccfSSadaf Ebrahimi }
264*b7893ccfSSadaf Ebrahimi
265*b7893ccfSSadaf Ebrahimi // Validate pCreateInfo->pQueueCreateInfos
266*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pQueueCreateInfos) {
267*b7893ccfSSadaf Ebrahimi std::unordered_set<uint32_t> set;
268*b7893ccfSSadaf Ebrahimi
269*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; ++i) {
270*b7893ccfSSadaf Ebrahimi const uint32_t requested_queue_family = pCreateInfo->pQueueCreateInfos[i].queueFamilyIndex;
271*b7893ccfSSadaf Ebrahimi if (requested_queue_family == VK_QUEUE_FAMILY_IGNORED) {
272*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
273*b7893ccfSSadaf Ebrahimi HandleToUint64(physicalDevice), "VUID-VkDeviceQueueCreateInfo-queueFamilyIndex-00381",
274*b7893ccfSSadaf Ebrahimi "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32
275*b7893ccfSSadaf Ebrahimi "].queueFamilyIndex is VK_QUEUE_FAMILY_IGNORED, but it is required to provide a valid queue family "
276*b7893ccfSSadaf Ebrahimi "index value.",
277*b7893ccfSSadaf Ebrahimi i);
278*b7893ccfSSadaf Ebrahimi } else if (set.count(requested_queue_family)) {
279*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
280*b7893ccfSSadaf Ebrahimi HandleToUint64(physicalDevice), "VUID-VkDeviceCreateInfo-queueFamilyIndex-00372",
281*b7893ccfSSadaf Ebrahimi "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].queueFamilyIndex (=%" PRIu32
282*b7893ccfSSadaf Ebrahimi ") is not unique within pCreateInfo->pQueueCreateInfos array.",
283*b7893ccfSSadaf Ebrahimi i, requested_queue_family);
284*b7893ccfSSadaf Ebrahimi } else {
285*b7893ccfSSadaf Ebrahimi set.insert(requested_queue_family);
286*b7893ccfSSadaf Ebrahimi }
287*b7893ccfSSadaf Ebrahimi
288*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pQueueCreateInfos[i].pQueuePriorities != nullptr) {
289*b7893ccfSSadaf Ebrahimi for (uint32_t j = 0; j < pCreateInfo->pQueueCreateInfos[i].queueCount; ++j) {
290*b7893ccfSSadaf Ebrahimi const float queue_priority = pCreateInfo->pQueueCreateInfos[i].pQueuePriorities[j];
291*b7893ccfSSadaf Ebrahimi if (!(queue_priority >= 0.f) || !(queue_priority <= 1.f)) {
292*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
293*b7893ccfSSadaf Ebrahimi HandleToUint64(physicalDevice), "VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383",
294*b7893ccfSSadaf Ebrahimi "vkCreateDevice: pCreateInfo->pQueueCreateInfos[%" PRIu32 "].pQueuePriorities[%" PRIu32
295*b7893ccfSSadaf Ebrahimi "] (=%f) is not between 0 and 1 (inclusive).",
296*b7893ccfSSadaf Ebrahimi i, j, queue_priority);
297*b7893ccfSSadaf Ebrahimi }
298*b7893ccfSSadaf Ebrahimi }
299*b7893ccfSSadaf Ebrahimi }
300*b7893ccfSSadaf Ebrahimi }
301*b7893ccfSSadaf Ebrahimi }
302*b7893ccfSSadaf Ebrahimi
303*b7893ccfSSadaf Ebrahimi return skip;
304*b7893ccfSSadaf Ebrahimi }
305*b7893ccfSSadaf Ebrahimi
require_device_extension(bool flag,char const * function_name,char const * extension_name)306*b7893ccfSSadaf Ebrahimi bool StatelessValidation::require_device_extension(bool flag, char const *function_name, char const *extension_name) {
307*b7893ccfSSadaf Ebrahimi if (!flag) {
308*b7893ccfSSadaf Ebrahimi return log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
309*b7893ccfSSadaf Ebrahimi kVUID_PVError_ExtensionNotEnabled,
310*b7893ccfSSadaf Ebrahimi "%s() called even though the %s extension was not enabled for this VkDevice.", function_name,
311*b7893ccfSSadaf Ebrahimi extension_name);
312*b7893ccfSSadaf Ebrahimi }
313*b7893ccfSSadaf Ebrahimi
314*b7893ccfSSadaf Ebrahimi return false;
315*b7893ccfSSadaf Ebrahimi }
316*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateBuffer(VkDevice device,const VkBufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkBuffer * pBuffer)317*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
318*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
319*b7893ccfSSadaf Ebrahimi bool skip = false;
320*b7893ccfSSadaf Ebrahimi
321*b7893ccfSSadaf Ebrahimi const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, VK_NULL_HANDLE, "vkCreateBuffer"};
322*b7893ccfSSadaf Ebrahimi
323*b7893ccfSSadaf Ebrahimi if (pCreateInfo != nullptr) {
324*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->size, "pCreateInfo->size", "VUID-VkBufferCreateInfo-size-00912", log_misc);
325*b7893ccfSSadaf Ebrahimi
326*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
327*b7893ccfSSadaf Ebrahimi if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
328*b7893ccfSSadaf Ebrahimi // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
329*b7893ccfSSadaf Ebrahimi if (pCreateInfo->queueFamilyIndexCount <= 1) {
330*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
331*b7893ccfSSadaf Ebrahimi "VUID-VkBufferCreateInfo-sharingMode-00914",
332*b7893ccfSSadaf Ebrahimi "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
333*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
334*b7893ccfSSadaf Ebrahimi }
335*b7893ccfSSadaf Ebrahimi
336*b7893ccfSSadaf Ebrahimi // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
337*b7893ccfSSadaf Ebrahimi // queueFamilyIndexCount uint32_t values
338*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pQueueFamilyIndices == nullptr) {
339*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
340*b7893ccfSSadaf Ebrahimi "VUID-VkBufferCreateInfo-sharingMode-00913",
341*b7893ccfSSadaf Ebrahimi "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
342*b7893ccfSSadaf Ebrahimi "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
343*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount uint32_t values.");
344*b7893ccfSSadaf Ebrahimi }
345*b7893ccfSSadaf Ebrahimi }
346*b7893ccfSSadaf Ebrahimi
347*b7893ccfSSadaf Ebrahimi // If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain
348*b7893ccfSSadaf Ebrahimi // VK_BUFFER_CREATE_SPARSE_BINDING_BIT
349*b7893ccfSSadaf Ebrahimi if (((pCreateInfo->flags & (VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
350*b7893ccfSSadaf Ebrahimi ((pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
351*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
352*b7893ccfSSadaf Ebrahimi "VUID-VkBufferCreateInfo-flags-00918",
353*b7893ccfSSadaf Ebrahimi "vkCreateBuffer: if pCreateInfo->flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or "
354*b7893ccfSSadaf Ebrahimi "VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT.");
355*b7893ccfSSadaf Ebrahimi }
356*b7893ccfSSadaf Ebrahimi }
357*b7893ccfSSadaf Ebrahimi
358*b7893ccfSSadaf Ebrahimi return skip;
359*b7893ccfSSadaf Ebrahimi }
360*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateImage(VkDevice device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)361*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
362*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
363*b7893ccfSSadaf Ebrahimi bool skip = false;
364*b7893ccfSSadaf Ebrahimi
365*b7893ccfSSadaf Ebrahimi const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE, "vkCreateImage"};
366*b7893ccfSSadaf Ebrahimi
367*b7893ccfSSadaf Ebrahimi if (pCreateInfo != nullptr) {
368*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
369*b7893ccfSSadaf Ebrahimi if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
370*b7893ccfSSadaf Ebrahimi // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
371*b7893ccfSSadaf Ebrahimi if (pCreateInfo->queueFamilyIndexCount <= 1) {
372*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
373*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-sharingMode-00942",
374*b7893ccfSSadaf Ebrahimi "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
375*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
376*b7893ccfSSadaf Ebrahimi }
377*b7893ccfSSadaf Ebrahimi
378*b7893ccfSSadaf Ebrahimi // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
379*b7893ccfSSadaf Ebrahimi // queueFamilyIndexCount uint32_t values
380*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pQueueFamilyIndices == nullptr) {
381*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
382*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-sharingMode-00941",
383*b7893ccfSSadaf Ebrahimi "vkCreateImage(): if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
384*b7893ccfSSadaf Ebrahimi "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
385*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount uint32_t values.");
386*b7893ccfSSadaf Ebrahimi }
387*b7893ccfSSadaf Ebrahimi }
388*b7893ccfSSadaf Ebrahimi
389*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->extent.width, "pCreateInfo->extent.width",
390*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-extent-00944", log_misc);
391*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->extent.height, "pCreateInfo->extent.height",
392*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-extent-00945", log_misc);
393*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->extent.depth, "pCreateInfo->extent.depth",
394*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-extent-00946", log_misc);
395*b7893ccfSSadaf Ebrahimi
396*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->mipLevels, "pCreateInfo->mipLevels", "VUID-VkImageCreateInfo-mipLevels-00947",
397*b7893ccfSSadaf Ebrahimi log_misc);
398*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->arrayLayers, "pCreateInfo->arrayLayers",
399*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-arrayLayers-00948", log_misc);
400*b7893ccfSSadaf Ebrahimi
401*b7893ccfSSadaf Ebrahimi // InitialLayout must be PREINITIALIZED or UNDEFINED
402*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_UNDEFINED) &&
403*b7893ccfSSadaf Ebrahimi (pCreateInfo->initialLayout != VK_IMAGE_LAYOUT_PREINITIALIZED)) {
404*b7893ccfSSadaf Ebrahimi skip |= log_msg(
405*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
406*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-initialLayout-00993",
407*b7893ccfSSadaf Ebrahimi "vkCreateImage(): initialLayout is %s, must be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED.",
408*b7893ccfSSadaf Ebrahimi string_VkImageLayout(pCreateInfo->initialLayout));
409*b7893ccfSSadaf Ebrahimi }
410*b7893ccfSSadaf Ebrahimi
411*b7893ccfSSadaf Ebrahimi // If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1
412*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->imageType == VK_IMAGE_TYPE_1D) &&
413*b7893ccfSSadaf Ebrahimi ((pCreateInfo->extent.height != 1) || (pCreateInfo->extent.depth != 1))) {
414*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
415*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00956",
416*b7893ccfSSadaf Ebrahimi "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_1D, both pCreateInfo->extent.height and "
417*b7893ccfSSadaf Ebrahimi "pCreateInfo->extent.depth must be 1.");
418*b7893ccfSSadaf Ebrahimi }
419*b7893ccfSSadaf Ebrahimi
420*b7893ccfSSadaf Ebrahimi if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D) {
421*b7893ccfSSadaf Ebrahimi if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) {
422*b7893ccfSSadaf Ebrahimi if (pCreateInfo->extent.width != pCreateInfo->extent.height) {
423*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
424*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
425*b7893ccfSSadaf Ebrahimi "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
426*b7893ccfSSadaf Ebrahimi "pCreateInfo->extent.width (=%" PRIu32 ") and pCreateInfo->extent.height (=%" PRIu32
427*b7893ccfSSadaf Ebrahimi ") are not equal.",
428*b7893ccfSSadaf Ebrahimi pCreateInfo->extent.width, pCreateInfo->extent.height);
429*b7893ccfSSadaf Ebrahimi }
430*b7893ccfSSadaf Ebrahimi
431*b7893ccfSSadaf Ebrahimi if (pCreateInfo->arrayLayers < 6) {
432*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
433*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkImageCreateInfo-imageType-00954",
434*b7893ccfSSadaf Ebrahimi "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, but "
435*b7893ccfSSadaf Ebrahimi "pCreateInfo->arrayLayers (=%" PRIu32 ") is not greater than or equal to 6.",
436*b7893ccfSSadaf Ebrahimi pCreateInfo->arrayLayers);
437*b7893ccfSSadaf Ebrahimi }
438*b7893ccfSSadaf Ebrahimi }
439*b7893ccfSSadaf Ebrahimi
440*b7893ccfSSadaf Ebrahimi if (pCreateInfo->extent.depth != 1) {
441*b7893ccfSSadaf Ebrahimi skip |=
442*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
443*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00957",
444*b7893ccfSSadaf Ebrahimi "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_2D, pCreateInfo->extent.depth must be 1.");
445*b7893ccfSSadaf Ebrahimi }
446*b7893ccfSSadaf Ebrahimi }
447*b7893ccfSSadaf Ebrahimi
448*b7893ccfSSadaf Ebrahimi // 3D image may have only 1 layer
449*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->imageType == VK_IMAGE_TYPE_3D) && (pCreateInfo->arrayLayers != 1)) {
450*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
451*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00961",
452*b7893ccfSSadaf Ebrahimi "vkCreateImage(): if pCreateInfo->imageType is VK_IMAGE_TYPE_3D, pCreateInfo->arrayLayers must be 1.");
453*b7893ccfSSadaf Ebrahimi }
454*b7893ccfSSadaf Ebrahimi
455*b7893ccfSSadaf Ebrahimi // If multi-sample, validate type, usage, tiling and mip levels.
456*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) &&
457*b7893ccfSSadaf Ebrahimi ((pCreateInfo->imageType != VK_IMAGE_TYPE_2D) || (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) ||
458*b7893ccfSSadaf Ebrahimi (pCreateInfo->mipLevels != 1) || (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL))) {
459*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
460*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-samples-02257",
461*b7893ccfSSadaf Ebrahimi "vkCreateImage(): Multi-sample image with incompatible type, usage, tiling, or mips.");
462*b7893ccfSSadaf Ebrahimi }
463*b7893ccfSSadaf Ebrahimi
464*b7893ccfSSadaf Ebrahimi if (0 != (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)) {
465*b7893ccfSSadaf Ebrahimi VkImageUsageFlags legal_flags = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
466*b7893ccfSSadaf Ebrahimi VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
467*b7893ccfSSadaf Ebrahimi // At least one of the legal attachment bits must be set
468*b7893ccfSSadaf Ebrahimi if (0 == (pCreateInfo->usage & legal_flags)) {
469*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
470*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-usage-00966",
471*b7893ccfSSadaf Ebrahimi "vkCreateImage(): Transient attachment image without a compatible attachment flag set.");
472*b7893ccfSSadaf Ebrahimi }
473*b7893ccfSSadaf Ebrahimi // No flags other than the legal attachment bits may be set
474*b7893ccfSSadaf Ebrahimi legal_flags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
475*b7893ccfSSadaf Ebrahimi if (0 != (pCreateInfo->usage & ~legal_flags)) {
476*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
477*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-usage-00963",
478*b7893ccfSSadaf Ebrahimi "vkCreateImage(): Transient attachment image with incompatible usage flags set.");
479*b7893ccfSSadaf Ebrahimi }
480*b7893ccfSSadaf Ebrahimi }
481*b7893ccfSSadaf Ebrahimi
482*b7893ccfSSadaf Ebrahimi // mipLevels must be less than or equal to the number of levels in the complete mipmap chain
483*b7893ccfSSadaf Ebrahimi uint32_t maxDim = std::max(std::max(pCreateInfo->extent.width, pCreateInfo->extent.height), pCreateInfo->extent.depth);
484*b7893ccfSSadaf Ebrahimi // Max mip levels is different for corner-sampled images vs normal images.
485*b7893ccfSSadaf Ebrahimi uint32_t maxMipLevels = (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) ? (uint32_t)(ceil(log2(maxDim)))
486*b7893ccfSSadaf Ebrahimi : (uint32_t)(floor(log2(maxDim)) + 1);
487*b7893ccfSSadaf Ebrahimi if (maxDim > 0 && pCreateInfo->mipLevels > maxMipLevels) {
488*b7893ccfSSadaf Ebrahimi skip |=
489*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
490*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-mipLevels-00958",
491*b7893ccfSSadaf Ebrahimi "vkCreateImage(): pCreateInfo->mipLevels must be less than or equal to "
492*b7893ccfSSadaf Ebrahimi "floor(log2(max(pCreateInfo->extent.width, pCreateInfo->extent.height, pCreateInfo->extent.depth)))+1.");
493*b7893ccfSSadaf Ebrahimi }
494*b7893ccfSSadaf Ebrahimi
495*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT) && (pCreateInfo->imageType != VK_IMAGE_TYPE_3D)) {
496*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE,
497*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-00950",
498*b7893ccfSSadaf Ebrahimi "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT but "
499*b7893ccfSSadaf Ebrahimi "pCreateInfo->imageType is not VK_IMAGE_TYPE_3D.");
500*b7893ccfSSadaf Ebrahimi }
501*b7893ccfSSadaf Ebrahimi
502*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && (!physical_device_features.sparseBinding)) {
503*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, VK_NULL_HANDLE,
504*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-00969",
505*b7893ccfSSadaf Ebrahimi "vkCreateImage(): pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_BINDING_BIT, but the "
506*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceFeatures::sparseBinding feature is disabled.");
507*b7893ccfSSadaf Ebrahimi }
508*b7893ccfSSadaf Ebrahimi
509*b7893ccfSSadaf Ebrahimi // If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain
510*b7893ccfSSadaf Ebrahimi // VK_IMAGE_CREATE_SPARSE_BINDING_BIT
511*b7893ccfSSadaf Ebrahimi if (((pCreateInfo->flags & (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) != 0) &&
512*b7893ccfSSadaf Ebrahimi ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) != VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
513*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
514*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-00987",
515*b7893ccfSSadaf Ebrahimi "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or "
516*b7893ccfSSadaf Ebrahimi "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT.");
517*b7893ccfSSadaf Ebrahimi }
518*b7893ccfSSadaf Ebrahimi
519*b7893ccfSSadaf Ebrahimi // Check for combinations of attributes that are incompatible with having VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT set
520*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) != 0) {
521*b7893ccfSSadaf Ebrahimi // Linear tiling is unsupported
522*b7893ccfSSadaf Ebrahimi if (VK_IMAGE_TILING_LINEAR == pCreateInfo->tiling) {
523*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
524*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidUsage,
525*b7893ccfSSadaf Ebrahimi "vkCreateImage: if pCreateInfo->flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT then image "
526*b7893ccfSSadaf Ebrahimi "tiling of VK_IMAGE_TILING_LINEAR is not supported");
527*b7893ccfSSadaf Ebrahimi }
528*b7893ccfSSadaf Ebrahimi
529*b7893ccfSSadaf Ebrahimi // Sparse 1D image isn't valid
530*b7893ccfSSadaf Ebrahimi if (VK_IMAGE_TYPE_1D == pCreateInfo->imageType) {
531*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
532*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00970",
533*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 1D image.");
534*b7893ccfSSadaf Ebrahimi }
535*b7893ccfSSadaf Ebrahimi
536*b7893ccfSSadaf Ebrahimi // Sparse 2D image when device doesn't support it
537*b7893ccfSSadaf Ebrahimi if ((VK_FALSE == physical_device_features.sparseResidencyImage2D) && (VK_IMAGE_TYPE_2D == pCreateInfo->imageType)) {
538*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
539*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00971",
540*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2D image if corresponding "
541*b7893ccfSSadaf Ebrahimi "feature is not enabled on the device.");
542*b7893ccfSSadaf Ebrahimi }
543*b7893ccfSSadaf Ebrahimi
544*b7893ccfSSadaf Ebrahimi // Sparse 3D image when device doesn't support it
545*b7893ccfSSadaf Ebrahimi if ((VK_FALSE == physical_device_features.sparseResidencyImage3D) && (VK_IMAGE_TYPE_3D == pCreateInfo->imageType)) {
546*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
547*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00972",
548*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 3D image if corresponding "
549*b7893ccfSSadaf Ebrahimi "feature is not enabled on the device.");
550*b7893ccfSSadaf Ebrahimi }
551*b7893ccfSSadaf Ebrahimi
552*b7893ccfSSadaf Ebrahimi // Multi-sample 2D image when device doesn't support it
553*b7893ccfSSadaf Ebrahimi if (VK_IMAGE_TYPE_2D == pCreateInfo->imageType) {
554*b7893ccfSSadaf Ebrahimi if ((VK_FALSE == physical_device_features.sparseResidency2Samples) &&
555*b7893ccfSSadaf Ebrahimi (VK_SAMPLE_COUNT_2_BIT == pCreateInfo->samples)) {
556*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
557*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00973",
558*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 2-sample image if "
559*b7893ccfSSadaf Ebrahimi "corresponding feature is not enabled on the device.");
560*b7893ccfSSadaf Ebrahimi } else if ((VK_FALSE == physical_device_features.sparseResidency4Samples) &&
561*b7893ccfSSadaf Ebrahimi (VK_SAMPLE_COUNT_4_BIT == pCreateInfo->samples)) {
562*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
563*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00974",
564*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 4-sample image if "
565*b7893ccfSSadaf Ebrahimi "corresponding feature is not enabled on the device.");
566*b7893ccfSSadaf Ebrahimi } else if ((VK_FALSE == physical_device_features.sparseResidency8Samples) &&
567*b7893ccfSSadaf Ebrahimi (VK_SAMPLE_COUNT_8_BIT == pCreateInfo->samples)) {
568*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
569*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00975",
570*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 8-sample image if "
571*b7893ccfSSadaf Ebrahimi "corresponding feature is not enabled on the device.");
572*b7893ccfSSadaf Ebrahimi } else if ((VK_FALSE == physical_device_features.sparseResidency16Samples) &&
573*b7893ccfSSadaf Ebrahimi (VK_SAMPLE_COUNT_16_BIT == pCreateInfo->samples)) {
574*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
575*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-00976",
576*b7893ccfSSadaf Ebrahimi "vkCreateImage: cannot specify VK_IMAGE_CREATE_SPARSE_BINDING_BIT for 16-sample image if "
577*b7893ccfSSadaf Ebrahimi "corresponding feature is not enabled on the device.");
578*b7893ccfSSadaf Ebrahimi }
579*b7893ccfSSadaf Ebrahimi }
580*b7893ccfSSadaf Ebrahimi }
581*b7893ccfSSadaf Ebrahimi
582*b7893ccfSSadaf Ebrahimi if (pCreateInfo->usage & VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV) {
583*b7893ccfSSadaf Ebrahimi if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D) {
584*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
585*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-imageType-02082",
586*b7893ccfSSadaf Ebrahimi "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
587*b7893ccfSSadaf Ebrahimi "imageType must be VK_IMAGE_TYPE_2D.");
588*b7893ccfSSadaf Ebrahimi }
589*b7893ccfSSadaf Ebrahimi if (pCreateInfo->samples != VK_SAMPLE_COUNT_1_BIT) {
590*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
591*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-samples-02083",
592*b7893ccfSSadaf Ebrahimi "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
593*b7893ccfSSadaf Ebrahimi "samples must be VK_SAMPLE_COUNT_1_BIT.");
594*b7893ccfSSadaf Ebrahimi }
595*b7893ccfSSadaf Ebrahimi if (pCreateInfo->tiling != VK_IMAGE_TILING_OPTIMAL) {
596*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
597*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-tiling-02084",
598*b7893ccfSSadaf Ebrahimi "vkCreateImage: if usage includes VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV, "
599*b7893ccfSSadaf Ebrahimi "tiling must be VK_IMAGE_TILING_OPTIMAL.");
600*b7893ccfSSadaf Ebrahimi }
601*b7893ccfSSadaf Ebrahimi }
602*b7893ccfSSadaf Ebrahimi
603*b7893ccfSSadaf Ebrahimi if (pCreateInfo->flags & VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV) {
604*b7893ccfSSadaf Ebrahimi if (pCreateInfo->imageType != VK_IMAGE_TYPE_2D && pCreateInfo->imageType != VK_IMAGE_TYPE_3D) {
605*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
606*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-02050",
607*b7893ccfSSadaf Ebrahimi "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
608*b7893ccfSSadaf Ebrahimi "imageType must be VK_IMAGE_TYPE_2D or VK_IMAGE_TYPE_3D.");
609*b7893ccfSSadaf Ebrahimi }
610*b7893ccfSSadaf Ebrahimi
611*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || FormatIsDepthOrStencil(pCreateInfo->format)) {
612*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
613*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-02051",
614*b7893ccfSSadaf Ebrahimi "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV, "
615*b7893ccfSSadaf Ebrahimi "it must not also contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT and format must "
616*b7893ccfSSadaf Ebrahimi "not be a depth/stencil format.");
617*b7893ccfSSadaf Ebrahimi }
618*b7893ccfSSadaf Ebrahimi
619*b7893ccfSSadaf Ebrahimi if (pCreateInfo->imageType == VK_IMAGE_TYPE_2D && (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1)) {
620*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
621*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-02052",
622*b7893ccfSSadaf Ebrahimi "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
623*b7893ccfSSadaf Ebrahimi "imageType is VK_IMAGE_TYPE_2D, extent.width and extent.height must be "
624*b7893ccfSSadaf Ebrahimi "greater than 1.");
625*b7893ccfSSadaf Ebrahimi } else if (pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
626*b7893ccfSSadaf Ebrahimi (pCreateInfo->extent.width == 1 || pCreateInfo->extent.height == 1 || pCreateInfo->extent.depth == 1)) {
627*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
628*b7893ccfSSadaf Ebrahimi "VUID-VkImageCreateInfo-flags-02053",
629*b7893ccfSSadaf Ebrahimi "vkCreateImage: If flags contains VK_IMAGE_CREATE_CORNER_SAMPLED_BIT_NV and "
630*b7893ccfSSadaf Ebrahimi "imageType is VK_IMAGE_TYPE_3D, extent.width, extent.height, and extent.depth "
631*b7893ccfSSadaf Ebrahimi "must be greater than 1.");
632*b7893ccfSSadaf Ebrahimi }
633*b7893ccfSSadaf Ebrahimi }
634*b7893ccfSSadaf Ebrahimi }
635*b7893ccfSSadaf Ebrahimi
636*b7893ccfSSadaf Ebrahimi return skip;
637*b7893ccfSSadaf Ebrahimi }
638*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateViewport(const VkViewport & viewport,const char * fn_name,const ParameterName & parameter_name,VkDebugReportObjectTypeEXT object_type,uint64_t object=0)639*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateViewport(const VkViewport &viewport, const char *fn_name,
640*b7893ccfSSadaf Ebrahimi const ParameterName ¶meter_name,
641*b7893ccfSSadaf Ebrahimi VkDebugReportObjectTypeEXT object_type, uint64_t object = 0) {
642*b7893ccfSSadaf Ebrahimi bool skip = false;
643*b7893ccfSSadaf Ebrahimi
644*b7893ccfSSadaf Ebrahimi // Note: for numerical correctness
645*b7893ccfSSadaf Ebrahimi // - float comparisons should expect NaN (comparison always false).
646*b7893ccfSSadaf Ebrahimi // - VkPhysicalDeviceLimits::maxViewportDimensions is uint32_t, not float -> careful.
647*b7893ccfSSadaf Ebrahimi
648*b7893ccfSSadaf Ebrahimi const auto f_lte_u32_exact = [](const float v1_f, const uint32_t v2_u32) {
649*b7893ccfSSadaf Ebrahimi if (std::isnan(v1_f)) return false;
650*b7893ccfSSadaf Ebrahimi if (v1_f <= 0.0f) return true;
651*b7893ccfSSadaf Ebrahimi
652*b7893ccfSSadaf Ebrahimi float intpart;
653*b7893ccfSSadaf Ebrahimi const float fract = modff(v1_f, &intpart);
654*b7893ccfSSadaf Ebrahimi
655*b7893ccfSSadaf Ebrahimi assert(std::numeric_limits<float>::radix == 2);
656*b7893ccfSSadaf Ebrahimi const float u32_max_plus1 = ldexpf(1.0f, 32); // hopefully exact
657*b7893ccfSSadaf Ebrahimi if (intpart >= u32_max_plus1) return false;
658*b7893ccfSSadaf Ebrahimi
659*b7893ccfSSadaf Ebrahimi uint32_t v1_u32 = static_cast<uint32_t>(intpart);
660*b7893ccfSSadaf Ebrahimi if (v1_u32 < v2_u32)
661*b7893ccfSSadaf Ebrahimi return true;
662*b7893ccfSSadaf Ebrahimi else if (v1_u32 == v2_u32 && fract == 0.0f)
663*b7893ccfSSadaf Ebrahimi return true;
664*b7893ccfSSadaf Ebrahimi else
665*b7893ccfSSadaf Ebrahimi return false;
666*b7893ccfSSadaf Ebrahimi };
667*b7893ccfSSadaf Ebrahimi
668*b7893ccfSSadaf Ebrahimi const auto f_lte_u32_direct = [](const float v1_f, const uint32_t v2_u32) {
669*b7893ccfSSadaf Ebrahimi const float v2_f = static_cast<float>(v2_u32); // not accurate for > radix^digits; and undefined rounding mode
670*b7893ccfSSadaf Ebrahimi return (v1_f <= v2_f);
671*b7893ccfSSadaf Ebrahimi };
672*b7893ccfSSadaf Ebrahimi
673*b7893ccfSSadaf Ebrahimi // width
674*b7893ccfSSadaf Ebrahimi bool width_healthy = true;
675*b7893ccfSSadaf Ebrahimi const auto max_w = device_limits.maxViewportDimensions[0];
676*b7893ccfSSadaf Ebrahimi
677*b7893ccfSSadaf Ebrahimi if (!(viewport.width > 0.0f)) {
678*b7893ccfSSadaf Ebrahimi width_healthy = false;
679*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-width-01770",
680*b7893ccfSSadaf Ebrahimi "%s: %s.width (=%f) is not greater than 0.0.", fn_name, parameter_name.get_name().c_str(), viewport.width);
681*b7893ccfSSadaf Ebrahimi } else if (!(f_lte_u32_exact(viewport.width, max_w) || f_lte_u32_direct(viewport.width, max_w))) {
682*b7893ccfSSadaf Ebrahimi width_healthy = false;
683*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-width-01771",
684*b7893ccfSSadaf Ebrahimi "%s: %s.width (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32 ").", fn_name,
685*b7893ccfSSadaf Ebrahimi parameter_name.get_name().c_str(), viewport.width, max_w);
686*b7893ccfSSadaf Ebrahimi } else if (!f_lte_u32_exact(viewport.width, max_w) && f_lte_u32_direct(viewport.width, max_w)) {
687*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
688*b7893ccfSSadaf Ebrahimi "%s: %s.width (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[0] (=%" PRIu32
689*b7893ccfSSadaf Ebrahimi "), but it is within the static_cast<float>(maxViewportDimensions[0]) limit.",
690*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), viewport.width, max_w);
691*b7893ccfSSadaf Ebrahimi }
692*b7893ccfSSadaf Ebrahimi
693*b7893ccfSSadaf Ebrahimi // height
694*b7893ccfSSadaf Ebrahimi bool height_healthy = true;
695*b7893ccfSSadaf Ebrahimi const bool negative_height_enabled = api_version >= VK_API_VERSION_1_1 || device_extensions.vk_khr_maintenance1 ||
696*b7893ccfSSadaf Ebrahimi device_extensions.vk_amd_negative_viewport_height;
697*b7893ccfSSadaf Ebrahimi const auto max_h = device_limits.maxViewportDimensions[1];
698*b7893ccfSSadaf Ebrahimi
699*b7893ccfSSadaf Ebrahimi if (!negative_height_enabled && !(viewport.height > 0.0f)) {
700*b7893ccfSSadaf Ebrahimi height_healthy = false;
701*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-height-01772",
702*b7893ccfSSadaf Ebrahimi "%s: %s.height (=%f) is not greater 0.0.", fn_name, parameter_name.get_name().c_str(), viewport.height);
703*b7893ccfSSadaf Ebrahimi } else if (!(f_lte_u32_exact(fabsf(viewport.height), max_h) || f_lte_u32_direct(fabsf(viewport.height), max_h))) {
704*b7893ccfSSadaf Ebrahimi height_healthy = false;
705*b7893ccfSSadaf Ebrahimi
706*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-height-01773",
707*b7893ccfSSadaf Ebrahimi "%s: Absolute value of %s.height (=%f) exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
708*b7893ccfSSadaf Ebrahimi ").",
709*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), viewport.height, max_h);
710*b7893ccfSSadaf Ebrahimi } else if (!f_lte_u32_exact(fabsf(viewport.height), max_h) && f_lte_u32_direct(fabsf(viewport.height), max_h)) {
711*b7893ccfSSadaf Ebrahimi height_healthy = false;
712*b7893ccfSSadaf Ebrahimi
713*b7893ccfSSadaf Ebrahimi skip |= log_msg(
714*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, object_type, object, kVUID_PVError_NONE,
715*b7893ccfSSadaf Ebrahimi "%s: Absolute value of %s.height (=%f) technically exceeds VkPhysicalDeviceLimits::maxViewportDimensions[1] (=%" PRIu32
716*b7893ccfSSadaf Ebrahimi "), but it is within the static_cast<float>(maxViewportDimensions[1]) limit.",
717*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), viewport.height, max_h);
718*b7893ccfSSadaf Ebrahimi }
719*b7893ccfSSadaf Ebrahimi
720*b7893ccfSSadaf Ebrahimi // x
721*b7893ccfSSadaf Ebrahimi bool x_healthy = true;
722*b7893ccfSSadaf Ebrahimi if (!(viewport.x >= device_limits.viewportBoundsRange[0])) {
723*b7893ccfSSadaf Ebrahimi x_healthy = false;
724*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-x-01774",
725*b7893ccfSSadaf Ebrahimi "%s: %s.x (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name,
726*b7893ccfSSadaf Ebrahimi parameter_name.get_name().c_str(), viewport.x, device_limits.viewportBoundsRange[0]);
727*b7893ccfSSadaf Ebrahimi }
728*b7893ccfSSadaf Ebrahimi
729*b7893ccfSSadaf Ebrahimi // x + width
730*b7893ccfSSadaf Ebrahimi if (x_healthy && width_healthy) {
731*b7893ccfSSadaf Ebrahimi const float right_bound = viewport.x + viewport.width;
732*b7893ccfSSadaf Ebrahimi if (!(right_bound <= device_limits.viewportBoundsRange[1])) {
733*b7893ccfSSadaf Ebrahimi skip |=
734*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-x-01232",
735*b7893ccfSSadaf Ebrahimi "%s: %s.x + %s.width (=%f + %f = %f) is greater than VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
736*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), parameter_name.get_name().c_str(), viewport.x, viewport.width,
737*b7893ccfSSadaf Ebrahimi right_bound, device_limits.viewportBoundsRange[1]);
738*b7893ccfSSadaf Ebrahimi }
739*b7893ccfSSadaf Ebrahimi }
740*b7893ccfSSadaf Ebrahimi
741*b7893ccfSSadaf Ebrahimi // y
742*b7893ccfSSadaf Ebrahimi bool y_healthy = true;
743*b7893ccfSSadaf Ebrahimi if (!(viewport.y >= device_limits.viewportBoundsRange[0])) {
744*b7893ccfSSadaf Ebrahimi y_healthy = false;
745*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01775",
746*b7893ccfSSadaf Ebrahimi "%s: %s.y (=%f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).", fn_name,
747*b7893ccfSSadaf Ebrahimi parameter_name.get_name().c_str(), viewport.y, device_limits.viewportBoundsRange[0]);
748*b7893ccfSSadaf Ebrahimi } else if (negative_height_enabled && !(viewport.y <= device_limits.viewportBoundsRange[1])) {
749*b7893ccfSSadaf Ebrahimi y_healthy = false;
750*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01776",
751*b7893ccfSSadaf Ebrahimi "%s: %s.y (=%f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).", fn_name,
752*b7893ccfSSadaf Ebrahimi parameter_name.get_name().c_str(), viewport.y, device_limits.viewportBoundsRange[1]);
753*b7893ccfSSadaf Ebrahimi }
754*b7893ccfSSadaf Ebrahimi
755*b7893ccfSSadaf Ebrahimi // y + height
756*b7893ccfSSadaf Ebrahimi if (y_healthy && height_healthy) {
757*b7893ccfSSadaf Ebrahimi const float boundary = viewport.y + viewport.height;
758*b7893ccfSSadaf Ebrahimi
759*b7893ccfSSadaf Ebrahimi if (!(boundary <= device_limits.viewportBoundsRange[1])) {
760*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01233",
761*b7893ccfSSadaf Ebrahimi "%s: %s.y + %s.height (=%f + %f = %f) exceeds VkPhysicalDeviceLimits::viewportBoundsRange[1] (=%f).",
762*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), parameter_name.get_name().c_str(), viewport.y,
763*b7893ccfSSadaf Ebrahimi viewport.height, boundary, device_limits.viewportBoundsRange[1]);
764*b7893ccfSSadaf Ebrahimi } else if (negative_height_enabled && !(boundary >= device_limits.viewportBoundsRange[0])) {
765*b7893ccfSSadaf Ebrahimi skip |=
766*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-y-01777",
767*b7893ccfSSadaf Ebrahimi "%s: %s.y + %s.height (=%f + %f = %f) is less than VkPhysicalDeviceLimits::viewportBoundsRange[0] (=%f).",
768*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), parameter_name.get_name().c_str(), viewport.y, viewport.height,
769*b7893ccfSSadaf Ebrahimi boundary, device_limits.viewportBoundsRange[0]);
770*b7893ccfSSadaf Ebrahimi }
771*b7893ccfSSadaf Ebrahimi }
772*b7893ccfSSadaf Ebrahimi
773*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_ext_depth_range_unrestricted) {
774*b7893ccfSSadaf Ebrahimi // minDepth
775*b7893ccfSSadaf Ebrahimi if (!(viewport.minDepth >= 0.0) || !(viewport.minDepth <= 1.0)) {
776*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-minDepth-01234",
777*b7893ccfSSadaf Ebrahimi
778*b7893ccfSSadaf Ebrahimi "%s: VK_EXT_depth_range_unrestricted extension is not enabled and %s.minDepth (=%f) is not within the "
779*b7893ccfSSadaf Ebrahimi "[0.0, 1.0] range.",
780*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), viewport.minDepth);
781*b7893ccfSSadaf Ebrahimi }
782*b7893ccfSSadaf Ebrahimi
783*b7893ccfSSadaf Ebrahimi // maxDepth
784*b7893ccfSSadaf Ebrahimi if (!(viewport.maxDepth >= 0.0) || !(viewport.maxDepth <= 1.0)) {
785*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object, "VUID-VkViewport-maxDepth-01235",
786*b7893ccfSSadaf Ebrahimi
787*b7893ccfSSadaf Ebrahimi "%s: VK_EXT_depth_range_unrestricted extension is not enabled and %s.maxDepth (=%f) is not within the "
788*b7893ccfSSadaf Ebrahimi "[0.0, 1.0] range.",
789*b7893ccfSSadaf Ebrahimi fn_name, parameter_name.get_name().c_str(), viewport.maxDepth);
790*b7893ccfSSadaf Ebrahimi }
791*b7893ccfSSadaf Ebrahimi }
792*b7893ccfSSadaf Ebrahimi
793*b7893ccfSSadaf Ebrahimi return skip;
794*b7893ccfSSadaf Ebrahimi }
795*b7893ccfSSadaf Ebrahimi
796*b7893ccfSSadaf Ebrahimi struct SampleOrderInfo {
797*b7893ccfSSadaf Ebrahimi VkShadingRatePaletteEntryNV shadingRate;
798*b7893ccfSSadaf Ebrahimi uint32_t width;
799*b7893ccfSSadaf Ebrahimi uint32_t height;
800*b7893ccfSSadaf Ebrahimi };
801*b7893ccfSSadaf Ebrahimi
802*b7893ccfSSadaf Ebrahimi // All palette entries with more than one pixel per fragment
803*b7893ccfSSadaf Ebrahimi static SampleOrderInfo sampleOrderInfos[] = {
804*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_1X2_PIXELS_NV, 1, 2},
805*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X1_PIXELS_NV, 2, 1},
806*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X2_PIXELS_NV, 2, 2},
807*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X2_PIXELS_NV, 4, 2},
808*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_2X4_PIXELS_NV, 2, 4},
809*b7893ccfSSadaf Ebrahimi {VK_SHADING_RATE_PALETTE_ENTRY_1_INVOCATION_PER_4X4_PIXELS_NV, 4, 4},
810*b7893ccfSSadaf Ebrahimi };
811*b7893ccfSSadaf Ebrahimi
ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV * order)812*b7893ccfSSadaf Ebrahimi bool StatelessValidation::ValidateCoarseSampleOrderCustomNV(const VkCoarseSampleOrderCustomNV *order) {
813*b7893ccfSSadaf Ebrahimi bool skip = false;
814*b7893ccfSSadaf Ebrahimi
815*b7893ccfSSadaf Ebrahimi SampleOrderInfo *sampleOrderInfo;
816*b7893ccfSSadaf Ebrahimi uint32_t infoIdx = 0;
817*b7893ccfSSadaf Ebrahimi for (sampleOrderInfo = nullptr; infoIdx < ARRAY_SIZE(sampleOrderInfos); ++infoIdx) {
818*b7893ccfSSadaf Ebrahimi if (sampleOrderInfos[infoIdx].shadingRate == order->shadingRate) {
819*b7893ccfSSadaf Ebrahimi sampleOrderInfo = &sampleOrderInfos[infoIdx];
820*b7893ccfSSadaf Ebrahimi break;
821*b7893ccfSSadaf Ebrahimi }
822*b7893ccfSSadaf Ebrahimi }
823*b7893ccfSSadaf Ebrahimi
824*b7893ccfSSadaf Ebrahimi if (sampleOrderInfo == nullptr) {
825*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
826*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleOrderCustomNV-shadingRate-02073",
827*b7893ccfSSadaf Ebrahimi "VkCoarseSampleOrderCustomNV shadingRate must be a shading rate "
828*b7893ccfSSadaf Ebrahimi "that generates fragments with more than one pixel.");
829*b7893ccfSSadaf Ebrahimi return skip;
830*b7893ccfSSadaf Ebrahimi }
831*b7893ccfSSadaf Ebrahimi
832*b7893ccfSSadaf Ebrahimi if (order->sampleCount == 0 || (order->sampleCount & (order->sampleCount - 1)) ||
833*b7893ccfSSadaf Ebrahimi !(order->sampleCount & device_limits.framebufferNoAttachmentsSampleCounts)) {
834*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
835*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleOrderCustomNV-sampleCount-02074",
836*b7893ccfSSadaf Ebrahimi "VkCoarseSampleOrderCustomNV sampleCount (=%" PRIu32
837*b7893ccfSSadaf Ebrahimi ") must "
838*b7893ccfSSadaf Ebrahimi "correspond to a sample count enumerated in VkSampleCountFlags whose corresponding bit "
839*b7893ccfSSadaf Ebrahimi "is set in framebufferNoAttachmentsSampleCounts.",
840*b7893ccfSSadaf Ebrahimi order->sampleCount);
841*b7893ccfSSadaf Ebrahimi }
842*b7893ccfSSadaf Ebrahimi
843*b7893ccfSSadaf Ebrahimi if (order->sampleLocationCount != order->sampleCount * sampleOrderInfo->width * sampleOrderInfo->height) {
844*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
845*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02075",
846*b7893ccfSSadaf Ebrahimi "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
847*b7893ccfSSadaf Ebrahimi ") must "
848*b7893ccfSSadaf Ebrahimi "be equal to the product of sampleCount (=%" PRIu32
849*b7893ccfSSadaf Ebrahimi "), the fragment width for shadingRate "
850*b7893ccfSSadaf Ebrahimi "(=%" PRIu32 "), and the fragment height for shadingRate (=%" PRIu32 ").",
851*b7893ccfSSadaf Ebrahimi order->sampleLocationCount, order->sampleCount, sampleOrderInfo->width, sampleOrderInfo->height);
852*b7893ccfSSadaf Ebrahimi }
853*b7893ccfSSadaf Ebrahimi
854*b7893ccfSSadaf Ebrahimi if (order->sampleLocationCount > phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples) {
855*b7893ccfSSadaf Ebrahimi skip |= log_msg(
856*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
857*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleOrderCustomNV-sampleLocationCount-02076",
858*b7893ccfSSadaf Ebrahimi "VkCoarseSampleOrderCustomNV sampleLocationCount (=%" PRIu32
859*b7893ccfSSadaf Ebrahimi ") must "
860*b7893ccfSSadaf Ebrahimi "be less than or equal to VkPhysicalDeviceShadingRateImagePropertiesNV shadingRateMaxCoarseSamples (=%" PRIu32 ").",
861*b7893ccfSSadaf Ebrahimi order->sampleLocationCount, phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples);
862*b7893ccfSSadaf Ebrahimi }
863*b7893ccfSSadaf Ebrahimi
864*b7893ccfSSadaf Ebrahimi // Accumulate a bitmask tracking which (x,y,sample) tuples are seen. Expect
865*b7893ccfSSadaf Ebrahimi // the first width*height*sampleCount bits to all be set. Note: There is no
866*b7893ccfSSadaf Ebrahimi // guarantee that 64 bits is enough, but practically it's unlikely for an
867*b7893ccfSSadaf Ebrahimi // implementation to support more than 32 bits for samplemask.
868*b7893ccfSSadaf Ebrahimi assert(phys_dev_ext_props.shading_rate_image_props.shadingRateMaxCoarseSamples <= 64);
869*b7893ccfSSadaf Ebrahimi uint64_t sampleLocationsMask = 0;
870*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < order->sampleLocationCount; ++i) {
871*b7893ccfSSadaf Ebrahimi const VkCoarseSampleLocationNV *sampleLoc = &order->pSampleLocations[i];
872*b7893ccfSSadaf Ebrahimi if (sampleLoc->pixelX >= sampleOrderInfo->width) {
873*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
874*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleLocationNV-pixelX-02078",
875*b7893ccfSSadaf Ebrahimi "pixelX must be less than the width (in pixels) of the fragment.");
876*b7893ccfSSadaf Ebrahimi }
877*b7893ccfSSadaf Ebrahimi if (sampleLoc->pixelY >= sampleOrderInfo->height) {
878*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
879*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleLocationNV-pixelY-02079",
880*b7893ccfSSadaf Ebrahimi "pixelY must be less than the height (in pixels) of the fragment.");
881*b7893ccfSSadaf Ebrahimi }
882*b7893ccfSSadaf Ebrahimi if (sampleLoc->sample >= order->sampleCount) {
883*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
884*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleLocationNV-sample-02080",
885*b7893ccfSSadaf Ebrahimi "sample must be less than the number of coverage samples in each pixel belonging to the fragment.");
886*b7893ccfSSadaf Ebrahimi }
887*b7893ccfSSadaf Ebrahimi uint32_t idx = sampleLoc->sample + order->sampleCount * (sampleLoc->pixelX + sampleOrderInfo->width * sampleLoc->pixelY);
888*b7893ccfSSadaf Ebrahimi sampleLocationsMask |= 1ULL << idx;
889*b7893ccfSSadaf Ebrahimi }
890*b7893ccfSSadaf Ebrahimi
891*b7893ccfSSadaf Ebrahimi uint64_t expectedMask = (order->sampleLocationCount == 64) ? ~0ULL : ((1ULL << order->sampleLocationCount) - 1);
892*b7893ccfSSadaf Ebrahimi if (sampleLocationsMask != expectedMask) {
893*b7893ccfSSadaf Ebrahimi skip |= log_msg(
894*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
895*b7893ccfSSadaf Ebrahimi "VUID-VkCoarseSampleOrderCustomNV-pSampleLocations-02077",
896*b7893ccfSSadaf Ebrahimi "The array pSampleLocations must contain exactly one entry for "
897*b7893ccfSSadaf Ebrahimi "every combination of valid values for pixelX, pixelY, and sample in the structure VkCoarseSampleOrderCustomNV.");
898*b7893ccfSSadaf Ebrahimi }
899*b7893ccfSSadaf Ebrahimi
900*b7893ccfSSadaf Ebrahimi return skip;
901*b7893ccfSSadaf Ebrahimi }
902*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateGraphicsPipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)903*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache,
904*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount,
905*b7893ccfSSadaf Ebrahimi const VkGraphicsPipelineCreateInfo *pCreateInfos,
906*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
907*b7893ccfSSadaf Ebrahimi VkPipeline *pPipelines) {
908*b7893ccfSSadaf Ebrahimi bool skip = false;
909*b7893ccfSSadaf Ebrahimi
910*b7893ccfSSadaf Ebrahimi if (pCreateInfos != nullptr) {
911*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < createInfoCount; ++i) {
912*b7893ccfSSadaf Ebrahimi bool has_dynamic_viewport = false;
913*b7893ccfSSadaf Ebrahimi bool has_dynamic_scissor = false;
914*b7893ccfSSadaf Ebrahimi bool has_dynamic_line_width = false;
915*b7893ccfSSadaf Ebrahimi bool has_dynamic_viewport_w_scaling_nv = false;
916*b7893ccfSSadaf Ebrahimi bool has_dynamic_discard_rectangle_ext = false;
917*b7893ccfSSadaf Ebrahimi bool has_dynamic_sample_locations_ext = false;
918*b7893ccfSSadaf Ebrahimi bool has_dynamic_exclusive_scissor_nv = false;
919*b7893ccfSSadaf Ebrahimi bool has_dynamic_shading_rate_palette_nv = false;
920*b7893ccfSSadaf Ebrahimi bool has_dynamic_line_stipple = false;
921*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pDynamicState != nullptr) {
922*b7893ccfSSadaf Ebrahimi const auto &dynamic_state_info = *pCreateInfos[i].pDynamicState;
923*b7893ccfSSadaf Ebrahimi for (uint32_t state_index = 0; state_index < dynamic_state_info.dynamicStateCount; ++state_index) {
924*b7893ccfSSadaf Ebrahimi const auto &dynamic_state = dynamic_state_info.pDynamicStates[state_index];
925*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT) has_dynamic_viewport = true;
926*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_SCISSOR) has_dynamic_scissor = true;
927*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_LINE_WIDTH) has_dynamic_line_width = true;
928*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV) has_dynamic_viewport_w_scaling_nv = true;
929*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT) has_dynamic_discard_rectangle_ext = true;
930*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT) has_dynamic_sample_locations_ext = true;
931*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV) has_dynamic_exclusive_scissor_nv = true;
932*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV)
933*b7893ccfSSadaf Ebrahimi has_dynamic_shading_rate_palette_nv = true;
934*b7893ccfSSadaf Ebrahimi if (dynamic_state == VK_DYNAMIC_STATE_LINE_STIPPLE_EXT) has_dynamic_line_stipple = true;
935*b7893ccfSSadaf Ebrahimi }
936*b7893ccfSSadaf Ebrahimi }
937*b7893ccfSSadaf Ebrahimi
938*b7893ccfSSadaf Ebrahimi auto feedback_struct = lvl_find_in_chain<VkPipelineCreationFeedbackCreateInfoEXT>(pCreateInfos[i].pNext);
939*b7893ccfSSadaf Ebrahimi if ((feedback_struct != nullptr) &&
940*b7893ccfSSadaf Ebrahimi (feedback_struct->pipelineStageCreationFeedbackCount != pCreateInfos[i].stageCount)) {
941*b7893ccfSSadaf Ebrahimi skip |=
942*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
943*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02668",
944*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): in pCreateInfo[%" PRIu32
945*b7893ccfSSadaf Ebrahimi "], VkPipelineCreationFeedbackEXT::pipelineStageCreationFeedbackCount"
946*b7893ccfSSadaf Ebrahimi "(=%" PRIu32 ") must equal VkGraphicsPipelineCreateInfo::stageCount(=%" PRIu32 ").",
947*b7893ccfSSadaf Ebrahimi i, feedback_struct->pipelineStageCreationFeedbackCount, pCreateInfos[i].stageCount);
948*b7893ccfSSadaf Ebrahimi }
949*b7893ccfSSadaf Ebrahimi
950*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
951*b7893ccfSSadaf Ebrahimi
952*b7893ccfSSadaf Ebrahimi // Collect active stages
953*b7893ccfSSadaf Ebrahimi uint32_t active_shaders = 0;
954*b7893ccfSSadaf Ebrahimi for (uint32_t stages = 0; stages < pCreateInfos[i].stageCount; stages++) {
955*b7893ccfSSadaf Ebrahimi active_shaders |= pCreateInfos[i].pStages->stage;
956*b7893ccfSSadaf Ebrahimi }
957*b7893ccfSSadaf Ebrahimi
958*b7893ccfSSadaf Ebrahimi if ((active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) &&
959*b7893ccfSSadaf Ebrahimi (active_shaders & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) && (pCreateInfos[i].pTessellationState != nullptr)) {
960*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type("vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState",
961*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO",
962*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pTessellationState,
963*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, false, kVUIDUndefined,
964*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-sType-sType");
965*b7893ccfSSadaf Ebrahimi
966*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkPipelineTessellationStateCreateInfo[] = {
967*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO};
968*b7893ccfSSadaf Ebrahimi
969*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext("vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->pNext",
970*b7893ccfSSadaf Ebrahimi "VkPipelineTessellationDomainOriginStateCreateInfo",
971*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pTessellationState->pNext,
972*b7893ccfSSadaf Ebrahimi ARRAY_SIZE(allowed_structs_VkPipelineTessellationStateCreateInfo),
973*b7893ccfSSadaf Ebrahimi allowed_structs_VkPipelineTessellationStateCreateInfo, GeneratedVulkanHeaderVersion,
974*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-pNext-pNext");
975*b7893ccfSSadaf Ebrahimi
976*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags("vkCreateGraphicsPipelines", "pCreateInfos[i].pTessellationState->flags",
977*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pTessellationState->flags,
978*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-flags-zerobitmask");
979*b7893ccfSSadaf Ebrahimi }
980*b7893ccfSSadaf Ebrahimi
981*b7893ccfSSadaf Ebrahimi if (!(active_shaders & VK_SHADER_STAGE_MESH_BIT_NV) && (pCreateInfos[i].pInputAssemblyState != nullptr)) {
982*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type("vkCreateGraphicsPipelines", "pCreateInfos[i].pInputAssemblyState",
983*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO",
984*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pInputAssemblyState,
985*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, false, kVUIDUndefined,
986*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-sType-sType");
987*b7893ccfSSadaf Ebrahimi
988*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext("vkCreateGraphicsPipelines", "pCreateInfos[i].pInputAssemblyState->pNext", NULL,
989*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pInputAssemblyState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
990*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-pNext-pNext");
991*b7893ccfSSadaf Ebrahimi
992*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags("vkCreateGraphicsPipelines", "pCreateInfos[i].pInputAssemblyState->flags",
993*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pInputAssemblyState->flags,
994*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-flags-zerobitmask");
995*b7893ccfSSadaf Ebrahimi
996*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum("vkCreateGraphicsPipelines", "pCreateInfos[i].pInputAssemblyState->topology",
997*b7893ccfSSadaf Ebrahimi "VkPrimitiveTopology", AllVkPrimitiveTopologyEnums,
998*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pInputAssemblyState->topology,
999*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineInputAssemblyStateCreateInfo-topology-parameter");
1000*b7893ccfSSadaf Ebrahimi
1001*b7893ccfSSadaf Ebrahimi skip |= validate_bool32("vkCreateGraphicsPipelines", "pCreateInfos[i].pInputAssemblyState->primitiveRestartEnable",
1002*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pInputAssemblyState->primitiveRestartEnable);
1003*b7893ccfSSadaf Ebrahimi }
1004*b7893ccfSSadaf Ebrahimi
1005*b7893ccfSSadaf Ebrahimi if (!(active_shaders & VK_SHADER_STAGE_MESH_BIT_NV) && (pCreateInfos[i].pVertexInputState != nullptr)) {
1006*b7893ccfSSadaf Ebrahimi auto const &vertex_input_state = pCreateInfos[i].pVertexInputState;
1007*b7893ccfSSadaf Ebrahimi
1008*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pVertexInputState->flags != 0) {
1009*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1010*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-flags-zerobitmask",
1011*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pararameter "
1012*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pVertexInputState->flags (%u) is reserved and must be zero.",
1013*b7893ccfSSadaf Ebrahimi i, vertex_input_state->flags);
1014*b7893ccfSSadaf Ebrahimi }
1015*b7893ccfSSadaf Ebrahimi
1016*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkPipelineVertexInputStateCreateInfo[] = {
1017*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT};
1018*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext("vkCreateGraphicsPipelines", "pCreateInfos[i].pVertexInputState->pNext",
1019*b7893ccfSSadaf Ebrahimi "VkPipelineVertexInputDivisorStateCreateInfoEXT",
1020*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pVertexInputState->pNext, 1,
1021*b7893ccfSSadaf Ebrahimi allowed_structs_VkPipelineVertexInputStateCreateInfo, GeneratedVulkanHeaderVersion,
1022*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pNext-pNext");
1023*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type("vkCreateGraphicsPipelines", "pCreateInfos[i].pVertexInputState",
1024*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO", vertex_input_state,
1025*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, false, kVUIDUndefined,
1026*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-sType-sType");
1027*b7893ccfSSadaf Ebrahimi skip |=
1028*b7893ccfSSadaf Ebrahimi validate_array("vkCreateGraphicsPipelines", "pCreateInfos[i].pVertexInputState->vertexBindingDescriptionCount",
1029*b7893ccfSSadaf Ebrahimi "pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions",
1030*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pVertexInputState->vertexBindingDescriptionCount,
1031*b7893ccfSSadaf Ebrahimi &pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions, false, true, kVUIDUndefined,
1032*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-parameter");
1033*b7893ccfSSadaf Ebrahimi
1034*b7893ccfSSadaf Ebrahimi skip |= validate_array(
1035*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines", "pCreateInfos[i].pVertexInputState->vertexAttributeDescriptionCount",
1036*b7893ccfSSadaf Ebrahimi "pCreateInfos[i]->pVertexAttributeDescriptions", vertex_input_state->vertexAttributeDescriptionCount,
1037*b7893ccfSSadaf Ebrahimi &vertex_input_state->pVertexAttributeDescriptions, false, true, kVUIDUndefined,
1038*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-parameter");
1039*b7893ccfSSadaf Ebrahimi
1040*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions != NULL) {
1041*b7893ccfSSadaf Ebrahimi for (uint32_t vertexBindingDescriptionIndex = 0;
1042*b7893ccfSSadaf Ebrahimi vertexBindingDescriptionIndex < pCreateInfos[i].pVertexInputState->vertexBindingDescriptionCount;
1043*b7893ccfSSadaf Ebrahimi ++vertexBindingDescriptionIndex) {
1044*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1045*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1046*b7893ccfSSadaf Ebrahimi "pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions[j].inputRate", "VkVertexInputRate",
1047*b7893ccfSSadaf Ebrahimi AllVkVertexInputRateEnums,
1048*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pVertexInputState->pVertexBindingDescriptions[vertexBindingDescriptionIndex].inputRate,
1049*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDescription-inputRate-parameter");
1050*b7893ccfSSadaf Ebrahimi }
1051*b7893ccfSSadaf Ebrahimi }
1052*b7893ccfSSadaf Ebrahimi
1053*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pVertexInputState->pVertexAttributeDescriptions != NULL) {
1054*b7893ccfSSadaf Ebrahimi for (uint32_t vertexAttributeDescriptionIndex = 0;
1055*b7893ccfSSadaf Ebrahimi vertexAttributeDescriptionIndex < pCreateInfos[i].pVertexInputState->vertexAttributeDescriptionCount;
1056*b7893ccfSSadaf Ebrahimi ++vertexAttributeDescriptionIndex) {
1057*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1058*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1059*b7893ccfSSadaf Ebrahimi "pCreateInfos[i].pVertexInputState->pVertexAttributeDescriptions[i].format", "VkFormat",
1060*b7893ccfSSadaf Ebrahimi AllVkFormatEnums,
1061*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pVertexInputState->pVertexAttributeDescriptions[vertexAttributeDescriptionIndex].format,
1062*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-format-parameter");
1063*b7893ccfSSadaf Ebrahimi }
1064*b7893ccfSSadaf Ebrahimi }
1065*b7893ccfSSadaf Ebrahimi
1066*b7893ccfSSadaf Ebrahimi if (vertex_input_state->vertexBindingDescriptionCount > device_limits.maxVertexInputBindings) {
1067*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1068*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613",
1069*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pararameter "
1070*b7893ccfSSadaf Ebrahimi "pCreateInfo[%d].pVertexInputState->vertexBindingDescriptionCount (%u) is "
1071*b7893ccfSSadaf Ebrahimi "greater than VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
1072*b7893ccfSSadaf Ebrahimi i, vertex_input_state->vertexBindingDescriptionCount, device_limits.maxVertexInputBindings);
1073*b7893ccfSSadaf Ebrahimi }
1074*b7893ccfSSadaf Ebrahimi
1075*b7893ccfSSadaf Ebrahimi if (vertex_input_state->vertexAttributeDescriptionCount > device_limits.maxVertexInputAttributes) {
1076*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1077*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-vertexAttributeDescriptionCount-00614",
1078*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pararameter "
1079*b7893ccfSSadaf Ebrahimi "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptionCount (%u) is "
1080*b7893ccfSSadaf Ebrahimi "greater than VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
1081*b7893ccfSSadaf Ebrahimi i, vertex_input_state->vertexAttributeDescriptionCount, device_limits.maxVertexInputAttributes);
1082*b7893ccfSSadaf Ebrahimi }
1083*b7893ccfSSadaf Ebrahimi
1084*b7893ccfSSadaf Ebrahimi std::unordered_set<uint32_t> vertex_bindings(vertex_input_state->vertexBindingDescriptionCount);
1085*b7893ccfSSadaf Ebrahimi for (uint32_t d = 0; d < vertex_input_state->vertexBindingDescriptionCount; ++d) {
1086*b7893ccfSSadaf Ebrahimi auto const &vertex_bind_desc = vertex_input_state->pVertexBindingDescriptions[d];
1087*b7893ccfSSadaf Ebrahimi auto const &binding_it = vertex_bindings.find(vertex_bind_desc.binding);
1088*b7893ccfSSadaf Ebrahimi if (binding_it != vertex_bindings.cend()) {
1089*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1090*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexBindingDescriptions-00616",
1091*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1092*b7893ccfSSadaf Ebrahimi "pCreateInfo[%d].pVertexInputState->pVertexBindingDescription[%d].binding "
1093*b7893ccfSSadaf Ebrahimi "(%" PRIu32 ") is not distinct.",
1094*b7893ccfSSadaf Ebrahimi i, d, vertex_bind_desc.binding);
1095*b7893ccfSSadaf Ebrahimi }
1096*b7893ccfSSadaf Ebrahimi vertex_bindings.insert(vertex_bind_desc.binding);
1097*b7893ccfSSadaf Ebrahimi
1098*b7893ccfSSadaf Ebrahimi if (vertex_bind_desc.binding >= device_limits.maxVertexInputBindings) {
1099*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1100*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDescription-binding-00618",
1101*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1102*b7893ccfSSadaf Ebrahimi "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].binding (%u) is "
1103*b7893ccfSSadaf Ebrahimi "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
1104*b7893ccfSSadaf Ebrahimi i, d, vertex_bind_desc.binding, device_limits.maxVertexInputBindings);
1105*b7893ccfSSadaf Ebrahimi }
1106*b7893ccfSSadaf Ebrahimi
1107*b7893ccfSSadaf Ebrahimi if (vertex_bind_desc.stride > device_limits.maxVertexInputBindingStride) {
1108*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1109*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputBindingDescription-stride-00619",
1110*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1111*b7893ccfSSadaf Ebrahimi "pCreateInfos[%u].pVertexInputState->pVertexBindingDescriptions[%u].stride (%u) is greater "
1112*b7893ccfSSadaf Ebrahimi "than VkPhysicalDeviceLimits::maxVertexInputBindingStride (%u).",
1113*b7893ccfSSadaf Ebrahimi i, d, vertex_bind_desc.stride, device_limits.maxVertexInputBindingStride);
1114*b7893ccfSSadaf Ebrahimi }
1115*b7893ccfSSadaf Ebrahimi }
1116*b7893ccfSSadaf Ebrahimi
1117*b7893ccfSSadaf Ebrahimi std::unordered_set<uint32_t> attribute_locations(vertex_input_state->vertexAttributeDescriptionCount);
1118*b7893ccfSSadaf Ebrahimi for (uint32_t d = 0; d < vertex_input_state->vertexAttributeDescriptionCount; ++d) {
1119*b7893ccfSSadaf Ebrahimi auto const &vertex_attrib_desc = vertex_input_state->pVertexAttributeDescriptions[d];
1120*b7893ccfSSadaf Ebrahimi auto const &location_it = attribute_locations.find(vertex_attrib_desc.location);
1121*b7893ccfSSadaf Ebrahimi if (location_it != attribute_locations.cend()) {
1122*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1123*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1124*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-pVertexAttributeDescriptions-00617",
1125*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1126*b7893ccfSSadaf Ebrahimi "pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].location (%u) is not distinct.",
1127*b7893ccfSSadaf Ebrahimi i, d, vertex_attrib_desc.location);
1128*b7893ccfSSadaf Ebrahimi }
1129*b7893ccfSSadaf Ebrahimi attribute_locations.insert(vertex_attrib_desc.location);
1130*b7893ccfSSadaf Ebrahimi
1131*b7893ccfSSadaf Ebrahimi auto const &binding_it = vertex_bindings.find(vertex_attrib_desc.binding);
1132*b7893ccfSSadaf Ebrahimi if (binding_it == vertex_bindings.cend()) {
1133*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1134*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1135*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineVertexInputStateCreateInfo-binding-00615",
1136*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1137*b7893ccfSSadaf Ebrahimi " pCreateInfo[%d].pVertexInputState->vertexAttributeDescriptions[%d].binding (%u) does not exist "
1138*b7893ccfSSadaf Ebrahimi "in any pCreateInfo[%d].pVertexInputState->pVertexBindingDescription.",
1139*b7893ccfSSadaf Ebrahimi i, d, vertex_attrib_desc.binding, i);
1140*b7893ccfSSadaf Ebrahimi }
1141*b7893ccfSSadaf Ebrahimi
1142*b7893ccfSSadaf Ebrahimi if (vertex_attrib_desc.location >= device_limits.maxVertexInputAttributes) {
1143*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1144*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-location-00620",
1145*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1146*b7893ccfSSadaf Ebrahimi "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].location (%u) is "
1147*b7893ccfSSadaf Ebrahimi "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes (%u).",
1148*b7893ccfSSadaf Ebrahimi i, d, vertex_attrib_desc.location, device_limits.maxVertexInputAttributes);
1149*b7893ccfSSadaf Ebrahimi }
1150*b7893ccfSSadaf Ebrahimi
1151*b7893ccfSSadaf Ebrahimi if (vertex_attrib_desc.binding >= device_limits.maxVertexInputBindings) {
1152*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1153*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-binding-00621",
1154*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1155*b7893ccfSSadaf Ebrahimi "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].binding (%u) is "
1156*b7893ccfSSadaf Ebrahimi "greater than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings (%u).",
1157*b7893ccfSSadaf Ebrahimi i, d, vertex_attrib_desc.binding, device_limits.maxVertexInputBindings);
1158*b7893ccfSSadaf Ebrahimi }
1159*b7893ccfSSadaf Ebrahimi
1160*b7893ccfSSadaf Ebrahimi if (vertex_attrib_desc.offset > device_limits.maxVertexInputAttributeOffset) {
1161*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1162*b7893ccfSSadaf Ebrahimi "VUID-VkVertexInputAttributeDescription-offset-00622",
1163*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter "
1164*b7893ccfSSadaf Ebrahimi "pCreateInfos[%u].pVertexInputState->pVertexAttributeDescriptions[%u].offset (%u) is "
1165*b7893ccfSSadaf Ebrahimi "greater than VkPhysicalDeviceLimits::maxVertexInputAttributeOffset (%u).",
1166*b7893ccfSSadaf Ebrahimi i, d, vertex_attrib_desc.offset, device_limits.maxVertexInputAttributeOffset);
1167*b7893ccfSSadaf Ebrahimi }
1168*b7893ccfSSadaf Ebrahimi }
1169*b7893ccfSSadaf Ebrahimi }
1170*b7893ccfSSadaf Ebrahimi
1171*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pStages != nullptr) {
1172*b7893ccfSSadaf Ebrahimi bool has_control = false;
1173*b7893ccfSSadaf Ebrahimi bool has_eval = false;
1174*b7893ccfSSadaf Ebrahimi
1175*b7893ccfSSadaf Ebrahimi for (uint32_t stage_index = 0; stage_index < pCreateInfos[i].stageCount; ++stage_index) {
1176*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
1177*b7893ccfSSadaf Ebrahimi has_control = true;
1178*b7893ccfSSadaf Ebrahimi } else if (pCreateInfos[i].pStages[stage_index].stage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
1179*b7893ccfSSadaf Ebrahimi has_eval = true;
1180*b7893ccfSSadaf Ebrahimi }
1181*b7893ccfSSadaf Ebrahimi }
1182*b7893ccfSSadaf Ebrahimi
1183*b7893ccfSSadaf Ebrahimi // pTessellationState is ignored without both tessellation control and tessellation evaluation shaders stages
1184*b7893ccfSSadaf Ebrahimi if (has_control && has_eval) {
1185*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pTessellationState == nullptr) {
1186*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1187*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-00731",
1188*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: if pCreateInfos[%d].pStages includes a tessellation control "
1189*b7893ccfSSadaf Ebrahimi "shader stage and a tessellation evaluation shader stage, "
1190*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pTessellationState must not be NULL.",
1191*b7893ccfSSadaf Ebrahimi i, i);
1192*b7893ccfSSadaf Ebrahimi } else {
1193*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_type =
1194*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
1195*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
1196*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1197*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pTessellationState->pNext", ParameterName::IndexVector{i}),
1198*b7893ccfSSadaf Ebrahimi "VkPipelineTessellationDomainOriginStateCreateInfo", pCreateInfos[i].pTessellationState->pNext, 1,
1199*b7893ccfSSadaf Ebrahimi &allowed_type, GeneratedVulkanHeaderVersion, "VUID-VkGraphicsPipelineCreateInfo-pNext-pNext");
1200*b7893ccfSSadaf Ebrahimi
1201*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(
1202*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1203*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pTessellationState->flags", ParameterName::IndexVector{i}),
1204*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pTessellationState->flags,
1205*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-flags-zerobitmask");
1206*b7893ccfSSadaf Ebrahimi
1207*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pTessellationState->sType !=
1208*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO) {
1209*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1210*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-sType-sType",
1211*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pTessellationState->sType must "
1212*b7893ccfSSadaf Ebrahimi "be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO.",
1213*b7893ccfSSadaf Ebrahimi i);
1214*b7893ccfSSadaf Ebrahimi }
1215*b7893ccfSSadaf Ebrahimi
1216*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pTessellationState->patchControlPoints == 0 ||
1217*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pTessellationState->patchControlPoints > device_limits.maxTessellationPatchSize) {
1218*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1219*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214",
1220*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: invalid parameter "
1221*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pTessellationState->patchControlPoints value %u. patchControlPoints "
1222*b7893ccfSSadaf Ebrahimi "should be >0 and <=%u.",
1223*b7893ccfSSadaf Ebrahimi i, pCreateInfos[i].pTessellationState->patchControlPoints,
1224*b7893ccfSSadaf Ebrahimi device_limits.maxTessellationPatchSize);
1225*b7893ccfSSadaf Ebrahimi }
1226*b7893ccfSSadaf Ebrahimi }
1227*b7893ccfSSadaf Ebrahimi }
1228*b7893ccfSSadaf Ebrahimi }
1229*b7893ccfSSadaf Ebrahimi
1230*b7893ccfSSadaf Ebrahimi // pViewportState, pMultisampleState, pDepthStencilState, and pColorBlendState ignored when rasterization is disabled
1231*b7893ccfSSadaf Ebrahimi if ((pCreateInfos[i].pRasterizationState != nullptr) &&
1232*b7893ccfSSadaf Ebrahimi (pCreateInfos[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
1233*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pViewportState == nullptr) {
1234*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1235*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750",
1236*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: Rasterization is enabled (pCreateInfos[%" PRIu32
1237*b7893ccfSSadaf Ebrahimi "].pRasterizationState->rasterizerDiscardEnable is VK_FALSE), but pCreateInfos[%" PRIu32
1238*b7893ccfSSadaf Ebrahimi "].pViewportState (=NULL) is not a valid pointer.",
1239*b7893ccfSSadaf Ebrahimi i, i);
1240*b7893ccfSSadaf Ebrahimi } else {
1241*b7893ccfSSadaf Ebrahimi const auto &viewport_state = *pCreateInfos[i].pViewportState;
1242*b7893ccfSSadaf Ebrahimi
1243*b7893ccfSSadaf Ebrahimi if (viewport_state.sType != VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO) {
1244*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1245*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-sType-sType",
1246*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1247*b7893ccfSSadaf Ebrahimi "].pViewportState->sType is not VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO.",
1248*b7893ccfSSadaf Ebrahimi i);
1249*b7893ccfSSadaf Ebrahimi }
1250*b7893ccfSSadaf Ebrahimi
1251*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkPipelineViewportStateCreateInfo[] = {
1252*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
1253*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV,
1254*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV,
1255*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV,
1256*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV,
1257*b7893ccfSSadaf Ebrahimi };
1258*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
1259*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1260*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pViewportState->pNext", ParameterName::IndexVector{i}),
1261*b7893ccfSSadaf Ebrahimi "VkPipelineViewportSwizzleStateCreateInfoNV, VkPipelineViewportWScalingStateCreateInfoNV, "
1262*b7893ccfSSadaf Ebrahimi "VkPipelineViewportExclusiveScissorStateCreateInfoNV, VkPipelineViewportShadingRateImageStateCreateInfoNV, "
1263*b7893ccfSSadaf Ebrahimi "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV",
1264*b7893ccfSSadaf Ebrahimi viewport_state.pNext, ARRAY_SIZE(allowed_structs_VkPipelineViewportStateCreateInfo),
1265*b7893ccfSSadaf Ebrahimi allowed_structs_VkPipelineViewportStateCreateInfo, 65,
1266*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportStateCreateInfo-pNext-pNext");
1267*b7893ccfSSadaf Ebrahimi
1268*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(
1269*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1270*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pViewportState->flags", ParameterName::IndexVector{i}),
1271*b7893ccfSSadaf Ebrahimi viewport_state.flags, "VUID-VkPipelineViewportStateCreateInfo-flags-zerobitmask");
1272*b7893ccfSSadaf Ebrahimi
1273*b7893ccfSSadaf Ebrahimi auto exclusive_scissor_struct = lvl_find_in_chain<VkPipelineViewportExclusiveScissorStateCreateInfoNV>(
1274*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pViewportState->pNext);
1275*b7893ccfSSadaf Ebrahimi auto shading_rate_image_struct = lvl_find_in_chain<VkPipelineViewportShadingRateImageStateCreateInfoNV>(
1276*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pViewportState->pNext);
1277*b7893ccfSSadaf Ebrahimi auto coarse_sample_order_struct = lvl_find_in_chain<VkPipelineViewportCoarseSampleOrderStateCreateInfoNV>(
1278*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pViewportState->pNext);
1279*b7893ccfSSadaf Ebrahimi const auto vp_swizzle_struct =
1280*b7893ccfSSadaf Ebrahimi lvl_find_in_chain<VkPipelineViewportSwizzleStateCreateInfoNV>(pCreateInfos[i].pViewportState->pNext);
1281*b7893ccfSSadaf Ebrahimi
1282*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiViewport) {
1283*b7893ccfSSadaf Ebrahimi if (viewport_state.viewportCount != 1) {
1284*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1285*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01216",
1286*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1287*b7893ccfSSadaf Ebrahimi "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32
1288*b7893ccfSSadaf Ebrahimi ") is not 1.",
1289*b7893ccfSSadaf Ebrahimi i, viewport_state.viewportCount);
1290*b7893ccfSSadaf Ebrahimi }
1291*b7893ccfSSadaf Ebrahimi
1292*b7893ccfSSadaf Ebrahimi if (viewport_state.scissorCount != 1) {
1293*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1294*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01217",
1295*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1296*b7893ccfSSadaf Ebrahimi "disabled, but pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
1297*b7893ccfSSadaf Ebrahimi ") is not 1.",
1298*b7893ccfSSadaf Ebrahimi i, viewport_state.scissorCount);
1299*b7893ccfSSadaf Ebrahimi }
1300*b7893ccfSSadaf Ebrahimi
1301*b7893ccfSSadaf Ebrahimi if (exclusive_scissor_struct && (exclusive_scissor_struct->exclusiveScissorCount != 0 &&
1302*b7893ccfSSadaf Ebrahimi exclusive_scissor_struct->exclusiveScissorCount != 1)) {
1303*b7893ccfSSadaf Ebrahimi skip |=
1304*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1305*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
1306*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02027",
1307*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1308*b7893ccfSSadaf Ebrahimi "disabled, but pCreateInfos[%" PRIu32
1309*b7893ccfSSadaf Ebrahimi "] VkPipelineViewportExclusiveScissorStateCreateInfoNV::exclusiveScissorCount (=%" PRIu32
1310*b7893ccfSSadaf Ebrahimi ") is not 1.",
1311*b7893ccfSSadaf Ebrahimi i, exclusive_scissor_struct->exclusiveScissorCount);
1312*b7893ccfSSadaf Ebrahimi }
1313*b7893ccfSSadaf Ebrahimi
1314*b7893ccfSSadaf Ebrahimi if (shading_rate_image_struct &&
1315*b7893ccfSSadaf Ebrahimi (shading_rate_image_struct->viewportCount != 0 && shading_rate_image_struct->viewportCount != 1)) {
1316*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1317*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
1318*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02054",
1319*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The VkPhysicalDeviceFeatures::multiViewport feature is "
1320*b7893ccfSSadaf Ebrahimi "disabled, but pCreateInfos[%" PRIu32
1321*b7893ccfSSadaf Ebrahimi "] VkPipelineViewportShadingRateImageStateCreateInfoNV::viewportCount (=%" PRIu32
1322*b7893ccfSSadaf Ebrahimi ") is neither 0 nor 1.",
1323*b7893ccfSSadaf Ebrahimi i, shading_rate_image_struct->viewportCount);
1324*b7893ccfSSadaf Ebrahimi }
1325*b7893ccfSSadaf Ebrahimi
1326*b7893ccfSSadaf Ebrahimi } else { // multiViewport enabled
1327*b7893ccfSSadaf Ebrahimi if (viewport_state.viewportCount == 0) {
1328*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1329*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1330*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-arraylength",
1331*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->viewportCount is 0.", i);
1332*b7893ccfSSadaf Ebrahimi } else if (viewport_state.viewportCount > device_limits.maxViewports) {
1333*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1334*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-viewportCount-01218",
1335*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1336*b7893ccfSSadaf Ebrahimi "].pViewportState->viewportCount (=%" PRIu32
1337*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
1338*b7893ccfSSadaf Ebrahimi i, viewport_state.viewportCount, device_limits.maxViewports);
1339*b7893ccfSSadaf Ebrahimi }
1340*b7893ccfSSadaf Ebrahimi
1341*b7893ccfSSadaf Ebrahimi if (viewport_state.scissorCount == 0) {
1342*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1343*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1344*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-arraylength",
1345*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount is 0.", i);
1346*b7893ccfSSadaf Ebrahimi } else if (viewport_state.scissorCount > device_limits.maxViewports) {
1347*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1348*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01219",
1349*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1350*b7893ccfSSadaf Ebrahimi "].pViewportState->scissorCount (=%" PRIu32
1351*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
1352*b7893ccfSSadaf Ebrahimi i, viewport_state.scissorCount, device_limits.maxViewports);
1353*b7893ccfSSadaf Ebrahimi }
1354*b7893ccfSSadaf Ebrahimi }
1355*b7893ccfSSadaf Ebrahimi
1356*b7893ccfSSadaf Ebrahimi if (exclusive_scissor_struct && exclusive_scissor_struct->exclusiveScissorCount > device_limits.maxViewports) {
1357*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1358*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
1359*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02028",
1360*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1361*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
1362*b7893ccfSSadaf Ebrahimi i, exclusive_scissor_struct->exclusiveScissorCount, device_limits.maxViewports);
1363*b7893ccfSSadaf Ebrahimi }
1364*b7893ccfSSadaf Ebrahimi
1365*b7893ccfSSadaf Ebrahimi if (shading_rate_image_struct && shading_rate_image_struct->viewportCount > device_limits.maxViewports) {
1366*b7893ccfSSadaf Ebrahimi skip |=
1367*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1368*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-viewportCount-02055",
1369*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1370*b7893ccfSSadaf Ebrahimi "] VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1371*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
1372*b7893ccfSSadaf Ebrahimi i, shading_rate_image_struct->viewportCount, device_limits.maxViewports);
1373*b7893ccfSSadaf Ebrahimi }
1374*b7893ccfSSadaf Ebrahimi
1375*b7893ccfSSadaf Ebrahimi if (viewport_state.scissorCount != viewport_state.viewportCount) {
1376*b7893ccfSSadaf Ebrahimi skip |=
1377*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1378*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportStateCreateInfo-scissorCount-01220",
1379*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "].pViewportState->scissorCount (=%" PRIu32
1380*b7893ccfSSadaf Ebrahimi ") is not identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1381*b7893ccfSSadaf Ebrahimi i, viewport_state.scissorCount, i, viewport_state.viewportCount);
1382*b7893ccfSSadaf Ebrahimi }
1383*b7893ccfSSadaf Ebrahimi
1384*b7893ccfSSadaf Ebrahimi if (exclusive_scissor_struct && exclusive_scissor_struct->exclusiveScissorCount != 0 &&
1385*b7893ccfSSadaf Ebrahimi exclusive_scissor_struct->exclusiveScissorCount != viewport_state.viewportCount) {
1386*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1387*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
1388*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-exclusiveScissorCount-02029",
1389*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32 "] exclusiveScissorCount (=%" PRIu32
1390*b7893ccfSSadaf Ebrahimi ") must be zero or identical to pCreateInfos[%" PRIu32
1391*b7893ccfSSadaf Ebrahimi "].pViewportState->viewportCount (=%" PRIu32 ").",
1392*b7893ccfSSadaf Ebrahimi i, exclusive_scissor_struct->exclusiveScissorCount, i, viewport_state.viewportCount);
1393*b7893ccfSSadaf Ebrahimi }
1394*b7893ccfSSadaf Ebrahimi
1395*b7893ccfSSadaf Ebrahimi if (shading_rate_image_struct && shading_rate_image_struct->shadingRateImageEnable &&
1396*b7893ccfSSadaf Ebrahimi shading_rate_image_struct->viewportCount != viewport_state.viewportCount) {
1397*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1398*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1399*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-shadingRateImageEnable-02056",
1400*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: If shadingRateImageEnable is enabled, pCreateInfos[%" PRIu32
1401*b7893ccfSSadaf Ebrahimi "] "
1402*b7893ccfSSadaf Ebrahimi "VkPipelineViewportShadingRateImageStateCreateInfoNV viewportCount (=%" PRIu32
1403*b7893ccfSSadaf Ebrahimi ") must identical to pCreateInfos[%" PRIu32 "].pViewportState->viewportCount (=%" PRIu32 ").",
1404*b7893ccfSSadaf Ebrahimi i, shading_rate_image_struct->viewportCount, i, viewport_state.viewportCount);
1405*b7893ccfSSadaf Ebrahimi }
1406*b7893ccfSSadaf Ebrahimi
1407*b7893ccfSSadaf Ebrahimi if (!has_dynamic_viewport && viewport_state.viewportCount > 0 && viewport_state.pViewports == nullptr) {
1408*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1409*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1410*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00747",
1411*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The viewport state is static (pCreateInfos[%" PRIu32
1412*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT), but pCreateInfos[%" PRIu32
1413*b7893ccfSSadaf Ebrahimi "].pViewportState->pViewports (=NULL) is an invalid pointer.",
1414*b7893ccfSSadaf Ebrahimi i, i);
1415*b7893ccfSSadaf Ebrahimi }
1416*b7893ccfSSadaf Ebrahimi
1417*b7893ccfSSadaf Ebrahimi if (!has_dynamic_scissor && viewport_state.scissorCount > 0 && viewport_state.pScissors == nullptr) {
1418*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1419*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1420*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00748",
1421*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The scissor state is static (pCreateInfos[%" PRIu32
1422*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_SCISSOR), but pCreateInfos[%" PRIu32
1423*b7893ccfSSadaf Ebrahimi "].pViewportState->pScissors (=NULL) is an invalid pointer.",
1424*b7893ccfSSadaf Ebrahimi i, i);
1425*b7893ccfSSadaf Ebrahimi }
1426*b7893ccfSSadaf Ebrahimi
1427*b7893ccfSSadaf Ebrahimi if (!has_dynamic_exclusive_scissor_nv && exclusive_scissor_struct &&
1428*b7893ccfSSadaf Ebrahimi exclusive_scissor_struct->exclusiveScissorCount > 0 &&
1429*b7893ccfSSadaf Ebrahimi exclusive_scissor_struct->pExclusiveScissors == nullptr) {
1430*b7893ccfSSadaf Ebrahimi skip |=
1431*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1432*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportExclusiveScissorStateCreateInfoNV-pDynamicStates-02030",
1433*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The exclusive scissor state is static (pCreateInfos[%" PRIu32
1434*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV), but "
1435*b7893ccfSSadaf Ebrahimi "pCreateInfos[%" PRIu32 "] pExclusiveScissors (=NULL) is an invalid pointer.",
1436*b7893ccfSSadaf Ebrahimi i, i);
1437*b7893ccfSSadaf Ebrahimi }
1438*b7893ccfSSadaf Ebrahimi
1439*b7893ccfSSadaf Ebrahimi if (!has_dynamic_shading_rate_palette_nv && shading_rate_image_struct &&
1440*b7893ccfSSadaf Ebrahimi shading_rate_image_struct->viewportCount > 0 &&
1441*b7893ccfSSadaf Ebrahimi shading_rate_image_struct->pShadingRatePalettes == nullptr) {
1442*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1443*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
1444*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportShadingRateImageStateCreateInfoNV-pDynamicStates-02057",
1445*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The shading rate palette state is static (pCreateInfos[%" PRIu32
1446*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV), "
1447*b7893ccfSSadaf Ebrahimi "but pCreateInfos[%" PRIu32 "] pShadingRatePalettes (=NULL) is an invalid pointer.",
1448*b7893ccfSSadaf Ebrahimi i, i);
1449*b7893ccfSSadaf Ebrahimi }
1450*b7893ccfSSadaf Ebrahimi
1451*b7893ccfSSadaf Ebrahimi if (vp_swizzle_struct) {
1452*b7893ccfSSadaf Ebrahimi if (vp_swizzle_struct->viewportCount != viewport_state.viewportCount) {
1453*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1454*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkPipelineViewportSwizzleStateCreateInfoNV-viewportCount-01215",
1455*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: The viewport swizzle state vieport count of %" PRIu32
1456*b7893ccfSSadaf Ebrahimi " does "
1457*b7893ccfSSadaf Ebrahimi "not match the viewport count of %" PRIu32 " in VkPipelineViewportStateCreateInfo.",
1458*b7893ccfSSadaf Ebrahimi vp_swizzle_struct->viewportCount, viewport_state.viewportCount);
1459*b7893ccfSSadaf Ebrahimi }
1460*b7893ccfSSadaf Ebrahimi }
1461*b7893ccfSSadaf Ebrahimi
1462*b7893ccfSSadaf Ebrahimi // validate the VkViewports
1463*b7893ccfSSadaf Ebrahimi if (!has_dynamic_viewport && viewport_state.pViewports) {
1464*b7893ccfSSadaf Ebrahimi for (uint32_t viewport_i = 0; viewport_i < viewport_state.viewportCount; ++viewport_i) {
1465*b7893ccfSSadaf Ebrahimi const auto &viewport = viewport_state.pViewports[viewport_i]; // will crash on invalid ptr
1466*b7893ccfSSadaf Ebrahimi const char *fn_name = "vkCreateGraphicsPipelines";
1467*b7893ccfSSadaf Ebrahimi skip |= manual_PreCallValidateViewport(viewport, fn_name,
1468*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pViewportState->pViewports[%i]",
1469*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, viewport_i}),
1470*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
1471*b7893ccfSSadaf Ebrahimi }
1472*b7893ccfSSadaf Ebrahimi }
1473*b7893ccfSSadaf Ebrahimi
1474*b7893ccfSSadaf Ebrahimi if (has_dynamic_viewport_w_scaling_nv && !device_extensions.vk_nv_clip_space_w_scaling) {
1475*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1476*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1477*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1478*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV, but "
1479*b7893ccfSSadaf Ebrahimi "VK_NV_clip_space_w_scaling extension is not enabled.",
1480*b7893ccfSSadaf Ebrahimi i);
1481*b7893ccfSSadaf Ebrahimi }
1482*b7893ccfSSadaf Ebrahimi
1483*b7893ccfSSadaf Ebrahimi if (has_dynamic_discard_rectangle_ext && !device_extensions.vk_ext_discard_rectangles) {
1484*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1485*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1486*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1487*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT, but "
1488*b7893ccfSSadaf Ebrahimi "VK_EXT_discard_rectangles extension is not enabled.",
1489*b7893ccfSSadaf Ebrahimi i);
1490*b7893ccfSSadaf Ebrahimi }
1491*b7893ccfSSadaf Ebrahimi
1492*b7893ccfSSadaf Ebrahimi if (has_dynamic_sample_locations_ext && !device_extensions.vk_ext_sample_locations) {
1493*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1494*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1495*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1496*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT, but "
1497*b7893ccfSSadaf Ebrahimi "VK_EXT_sample_locations extension is not enabled.",
1498*b7893ccfSSadaf Ebrahimi i);
1499*b7893ccfSSadaf Ebrahimi }
1500*b7893ccfSSadaf Ebrahimi
1501*b7893ccfSSadaf Ebrahimi if (has_dynamic_exclusive_scissor_nv && !device_extensions.vk_nv_scissor_exclusive) {
1502*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1503*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, kVUID_PVError_ExtensionNotEnabled,
1504*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1505*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates contains VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV, but "
1506*b7893ccfSSadaf Ebrahimi "VK_NV_scissor_exclusive extension is not enabled.",
1507*b7893ccfSSadaf Ebrahimi i);
1508*b7893ccfSSadaf Ebrahimi }
1509*b7893ccfSSadaf Ebrahimi
1510*b7893ccfSSadaf Ebrahimi if (coarse_sample_order_struct &&
1511*b7893ccfSSadaf Ebrahimi coarse_sample_order_struct->sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV &&
1512*b7893ccfSSadaf Ebrahimi coarse_sample_order_struct->customSampleOrderCount != 0) {
1513*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
1514*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE,
1515*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineViewportCoarseSampleOrderStateCreateInfoNV-sampleOrderType-02072",
1516*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: pCreateInfos[%" PRIu32
1517*b7893ccfSSadaf Ebrahimi "] "
1518*b7893ccfSSadaf Ebrahimi "VkPipelineViewportCoarseSampleOrderStateCreateInfoNV sampleOrderType is not "
1519*b7893ccfSSadaf Ebrahimi "VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV and customSampleOrderCount is not 0.",
1520*b7893ccfSSadaf Ebrahimi i);
1521*b7893ccfSSadaf Ebrahimi }
1522*b7893ccfSSadaf Ebrahimi
1523*b7893ccfSSadaf Ebrahimi if (coarse_sample_order_struct) {
1524*b7893ccfSSadaf Ebrahimi for (uint32_t order_i = 0; order_i < coarse_sample_order_struct->customSampleOrderCount; ++order_i) {
1525*b7893ccfSSadaf Ebrahimi skip |= ValidateCoarseSampleOrderCustomNV(&coarse_sample_order_struct->pCustomSampleOrders[order_i]);
1526*b7893ccfSSadaf Ebrahimi }
1527*b7893ccfSSadaf Ebrahimi }
1528*b7893ccfSSadaf Ebrahimi }
1529*b7893ccfSSadaf Ebrahimi
1530*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState == nullptr) {
1531*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1532*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00751",
1533*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: if pCreateInfos[%d].pRasterizationState->rasterizerDiscardEnable "
1534*b7893ccfSSadaf Ebrahimi "is VK_FALSE, pCreateInfos[%d].pMultisampleState must not be NULL.",
1535*b7893ccfSSadaf Ebrahimi i, i);
1536*b7893ccfSSadaf Ebrahimi } else {
1537*b7893ccfSSadaf Ebrahimi const VkStructureType valid_next_stypes[] = {LvlTypeMap<VkPipelineCoverageModulationStateCreateInfoNV>::kSType,
1538*b7893ccfSSadaf Ebrahimi LvlTypeMap<VkPipelineCoverageToColorStateCreateInfoNV>::kSType,
1539*b7893ccfSSadaf Ebrahimi LvlTypeMap<VkPipelineSampleLocationsStateCreateInfoEXT>::kSType};
1540*b7893ccfSSadaf Ebrahimi const char *valid_struct_names =
1541*b7893ccfSSadaf Ebrahimi "VkPipelineCoverageModulationStateCreateInfoNV, VkPipelineCoverageToColorStateCreateInfoNV, "
1542*b7893ccfSSadaf Ebrahimi "VkPipelineSampleLocationsStateCreateInfoEXT";
1543*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
1544*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1545*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->pNext", ParameterName::IndexVector{i}),
1546*b7893ccfSSadaf Ebrahimi valid_struct_names, pCreateInfos[i].pMultisampleState->pNext, 3, valid_next_stypes,
1547*b7893ccfSSadaf Ebrahimi GeneratedVulkanHeaderVersion, "VUID-VkPipelineMultisampleStateCreateInfo-pNext-pNext");
1548*b7893ccfSSadaf Ebrahimi
1549*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(
1550*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1551*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->flags", ParameterName::IndexVector{i}),
1552*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pMultisampleState->flags, "VUID-VkPipelineMultisampleStateCreateInfo-flags-zerobitmask");
1553*b7893ccfSSadaf Ebrahimi
1554*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1555*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1556*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->sampleShadingEnable", ParameterName::IndexVector{i}),
1557*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pMultisampleState->sampleShadingEnable);
1558*b7893ccfSSadaf Ebrahimi
1559*b7893ccfSSadaf Ebrahimi skip |= validate_array(
1560*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1561*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->rasterizationSamples", ParameterName::IndexVector{i}),
1562*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->pSampleMask", ParameterName::IndexVector{i}),
1563*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pMultisampleState->rasterizationSamples, &pCreateInfos[i].pMultisampleState->pSampleMask,
1564*b7893ccfSSadaf Ebrahimi true, false, kVUIDUndefined, kVUIDUndefined);
1565*b7893ccfSSadaf Ebrahimi
1566*b7893ccfSSadaf Ebrahimi skip |= validate_flags(
1567*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1568*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->rasterizationSamples", ParameterName::IndexVector{i}),
1569*b7893ccfSSadaf Ebrahimi "VkSampleCountFlagBits", AllVkSampleCountFlagBits, pCreateInfos[i].pMultisampleState->rasterizationSamples,
1570*b7893ccfSSadaf Ebrahimi kRequiredSingleBit, "VUID-VkPipelineMultisampleStateCreateInfo-rasterizationSamples-parameter");
1571*b7893ccfSSadaf Ebrahimi
1572*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1573*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1574*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->alphaToCoverageEnable", ParameterName::IndexVector{i}),
1575*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pMultisampleState->alphaToCoverageEnable);
1576*b7893ccfSSadaf Ebrahimi
1577*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1578*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1579*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pMultisampleState->alphaToOneEnable", ParameterName::IndexVector{i}),
1580*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pMultisampleState->alphaToOneEnable);
1581*b7893ccfSSadaf Ebrahimi
1582*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState->sType != VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO) {
1583*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1584*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidStructSType,
1585*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pMultisampleState->sType must be "
1586*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO",
1587*b7893ccfSSadaf Ebrahimi i);
1588*b7893ccfSSadaf Ebrahimi }
1589*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState->sampleShadingEnable == VK_TRUE) {
1590*b7893ccfSSadaf Ebrahimi if (!physical_device_features.sampleRateShading) {
1591*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1592*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-sampleShadingEnable-00784",
1593*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): parameter "
1594*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pMultisampleState->sampleShadingEnable.",
1595*b7893ccfSSadaf Ebrahimi i);
1596*b7893ccfSSadaf Ebrahimi }
1597*b7893ccfSSadaf Ebrahimi // TODO Add documentation issue about when minSampleShading must be in range and when it is ignored
1598*b7893ccfSSadaf Ebrahimi // For now a "least noise" test *only* when sampleShadingEnable is VK_TRUE.
1599*b7893ccfSSadaf Ebrahimi if (!in_inclusive_range(pCreateInfos[i].pMultisampleState->minSampleShading, 0.F, 1.0F)) {
1600*b7893ccfSSadaf Ebrahimi skip |= log_msg(
1601*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1602*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineMultisampleStateCreateInfo-minSampleShading-00786",
1603*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): parameter pCreateInfos[%d].pMultisampleState->minSampleShading.", i);
1604*b7893ccfSSadaf Ebrahimi }
1605*b7893ccfSSadaf Ebrahimi }
1606*b7893ccfSSadaf Ebrahimi
1607*b7893ccfSSadaf Ebrahimi const auto *line_state = lvl_find_in_chain<VkPipelineRasterizationLineStateCreateInfoEXT>(
1608*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pRasterizationState->pNext);
1609*b7893ccfSSadaf Ebrahimi
1610*b7893ccfSSadaf Ebrahimi if (line_state) {
1611*b7893ccfSSadaf Ebrahimi if ((line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT ||
1612*b7893ccfSSadaf Ebrahimi line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT)) {
1613*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState->alphaToCoverageEnable) {
1614*b7893ccfSSadaf Ebrahimi skip |=
1615*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1616*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-lineRasterizationMode-02766",
1617*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): Bresenham/Smooth line rasterization not supported with "
1618*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pMultisampleState->alphaToCoverageEnable == VK_TRUE.",
1619*b7893ccfSSadaf Ebrahimi i);
1620*b7893ccfSSadaf Ebrahimi }
1621*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState->alphaToOneEnable) {
1622*b7893ccfSSadaf Ebrahimi skip |=
1623*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1624*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-lineRasterizationMode-02766",
1625*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): Bresenham/Smooth line rasterization not supported with "
1626*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pMultisampleState->alphaToOneEnable == VK_TRUE.",
1627*b7893ccfSSadaf Ebrahimi i);
1628*b7893ccfSSadaf Ebrahimi }
1629*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pMultisampleState->sampleShadingEnable) {
1630*b7893ccfSSadaf Ebrahimi skip |=
1631*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1632*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-lineRasterizationMode-02766",
1633*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): Bresenham/Smooth line rasterization not supported with "
1634*b7893ccfSSadaf Ebrahimi "pCreateInfos[%d].pMultisampleState->sampleShadingEnable == VK_TRUE.",
1635*b7893ccfSSadaf Ebrahimi i);
1636*b7893ccfSSadaf Ebrahimi }
1637*b7893ccfSSadaf Ebrahimi }
1638*b7893ccfSSadaf Ebrahimi if (line_state->stippledLineEnable && !has_dynamic_line_stipple) {
1639*b7893ccfSSadaf Ebrahimi if (line_state->lineStippleFactor < 1 || line_state->lineStippleFactor > 256) {
1640*b7893ccfSSadaf Ebrahimi skip |=
1641*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1642*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-stippledLineEnable-02767",
1643*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineStippleFactor = %d must be in the "
1644*b7893ccfSSadaf Ebrahimi "range [1,256].",
1645*b7893ccfSSadaf Ebrahimi i, line_state->lineStippleFactor);
1646*b7893ccfSSadaf Ebrahimi }
1647*b7893ccfSSadaf Ebrahimi }
1648*b7893ccfSSadaf Ebrahimi const auto *line_features =
1649*b7893ccfSSadaf Ebrahimi lvl_find_in_chain<VkPhysicalDeviceLineRasterizationFeaturesEXT>(physical_device_features2.pNext);
1650*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT &&
1651*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->rectangularLines)) {
1652*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1653*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02768",
1654*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1655*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT requires the rectangularLines feature.",
1656*b7893ccfSSadaf Ebrahimi i);
1657*b7893ccfSSadaf Ebrahimi }
1658*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT &&
1659*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->bresenhamLines)) {
1660*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1661*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02769",
1662*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1663*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT requires the bresenhamLines feature.",
1664*b7893ccfSSadaf Ebrahimi i);
1665*b7893ccfSSadaf Ebrahimi }
1666*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT &&
1667*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->smoothLines)) {
1668*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1669*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-lineRasterizationMode-02770",
1670*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1671*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT requires the smoothLines feature.",
1672*b7893ccfSSadaf Ebrahimi i);
1673*b7893ccfSSadaf Ebrahimi }
1674*b7893ccfSSadaf Ebrahimi if (line_state->stippledLineEnable) {
1675*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT &&
1676*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->stippledRectangularLines)) {
1677*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
1678*b7893ccfSSadaf Ebrahimi 0, "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02771",
1679*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1680*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT with stipple requires the "
1681*b7893ccfSSadaf Ebrahimi "stippledRectangularLines feature.",
1682*b7893ccfSSadaf Ebrahimi i);
1683*b7893ccfSSadaf Ebrahimi }
1684*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT &&
1685*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->stippledBresenhamLines)) {
1686*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
1687*b7893ccfSSadaf Ebrahimi 0, "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02772",
1688*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1689*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT with stipple requires the "
1690*b7893ccfSSadaf Ebrahimi "stippledBresenhamLines feature.",
1691*b7893ccfSSadaf Ebrahimi i);
1692*b7893ccfSSadaf Ebrahimi }
1693*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT &&
1694*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->stippledSmoothLines)) {
1695*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
1696*b7893ccfSSadaf Ebrahimi 0, "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02773",
1697*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1698*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT with stipple requires the "
1699*b7893ccfSSadaf Ebrahimi "stippledSmoothLines feature.",
1700*b7893ccfSSadaf Ebrahimi i);
1701*b7893ccfSSadaf Ebrahimi }
1702*b7893ccfSSadaf Ebrahimi if (line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT &&
1703*b7893ccfSSadaf Ebrahimi (!line_features || !line_features->stippledSmoothLines || !device_limits.strictLines)) {
1704*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
1705*b7893ccfSSadaf Ebrahimi 0, "VUID-VkPipelineRasterizationLineStateCreateInfoEXT-stippledLineEnable-02774",
1706*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines(): pCreateInfos[%d] lineRasterizationMode = "
1707*b7893ccfSSadaf Ebrahimi "VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT with stipple requires the "
1708*b7893ccfSSadaf Ebrahimi "stippledRectangularLines and strictLines features.",
1709*b7893ccfSSadaf Ebrahimi i);
1710*b7893ccfSSadaf Ebrahimi }
1711*b7893ccfSSadaf Ebrahimi }
1712*b7893ccfSSadaf Ebrahimi }
1713*b7893ccfSSadaf Ebrahimi }
1714*b7893ccfSSadaf Ebrahimi
1715*b7893ccfSSadaf Ebrahimi bool uses_color_attachment = false;
1716*b7893ccfSSadaf Ebrahimi bool uses_depthstencil_attachment = false;
1717*b7893ccfSSadaf Ebrahimi {
1718*b7893ccfSSadaf Ebrahimi std::unique_lock<std::mutex> lock(renderpass_map_mutex);
1719*b7893ccfSSadaf Ebrahimi const auto subpasses_uses_it = renderpasses_states.find(pCreateInfos[i].renderPass);
1720*b7893ccfSSadaf Ebrahimi if (subpasses_uses_it != renderpasses_states.end()) {
1721*b7893ccfSSadaf Ebrahimi const auto &subpasses_uses = subpasses_uses_it->second;
1722*b7893ccfSSadaf Ebrahimi if (subpasses_uses.subpasses_using_color_attachment.count(pCreateInfos[i].subpass))
1723*b7893ccfSSadaf Ebrahimi uses_color_attachment = true;
1724*b7893ccfSSadaf Ebrahimi if (subpasses_uses.subpasses_using_depthstencil_attachment.count(pCreateInfos[i].subpass))
1725*b7893ccfSSadaf Ebrahimi uses_depthstencil_attachment = true;
1726*b7893ccfSSadaf Ebrahimi }
1727*b7893ccfSSadaf Ebrahimi lock.unlock();
1728*b7893ccfSSadaf Ebrahimi }
1729*b7893ccfSSadaf Ebrahimi
1730*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pDepthStencilState != nullptr && uses_depthstencil_attachment) {
1731*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
1732*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1733*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->pNext", ParameterName::IndexVector{i}), NULL,
1734*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->pNext, 0, NULL, GeneratedVulkanHeaderVersion,
1735*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineDepthStencilStateCreateInfo-pNext-pNext");
1736*b7893ccfSSadaf Ebrahimi
1737*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(
1738*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1739*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->flags", ParameterName::IndexVector{i}),
1740*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->flags, "VUID-VkPipelineDepthStencilStateCreateInfo-flags-zerobitmask");
1741*b7893ccfSSadaf Ebrahimi
1742*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1743*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1744*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->depthTestEnable", ParameterName::IndexVector{i}),
1745*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->depthTestEnable);
1746*b7893ccfSSadaf Ebrahimi
1747*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1748*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1749*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->depthWriteEnable", ParameterName::IndexVector{i}),
1750*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->depthWriteEnable);
1751*b7893ccfSSadaf Ebrahimi
1752*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1753*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1754*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->depthCompareOp", ParameterName::IndexVector{i}),
1755*b7893ccfSSadaf Ebrahimi "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->depthCompareOp,
1756*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
1757*b7893ccfSSadaf Ebrahimi
1758*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1759*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1760*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->depthBoundsTestEnable", ParameterName::IndexVector{i}),
1761*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->depthBoundsTestEnable);
1762*b7893ccfSSadaf Ebrahimi
1763*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1764*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1765*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->stencilTestEnable", ParameterName::IndexVector{i}),
1766*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pDepthStencilState->stencilTestEnable);
1767*b7893ccfSSadaf Ebrahimi
1768*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1769*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1770*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->front.failOp", ParameterName::IndexVector{i}),
1771*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.failOp,
1772*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-failOp-parameter");
1773*b7893ccfSSadaf Ebrahimi
1774*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1775*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1776*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->front.passOp", ParameterName::IndexVector{i}),
1777*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.passOp,
1778*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-passOp-parameter");
1779*b7893ccfSSadaf Ebrahimi
1780*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1781*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1782*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->front.depthFailOp", ParameterName::IndexVector{i}),
1783*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->front.depthFailOp,
1784*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-depthFailOp-parameter");
1785*b7893ccfSSadaf Ebrahimi
1786*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1787*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1788*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->front.compareOp", ParameterName::IndexVector{i}),
1789*b7893ccfSSadaf Ebrahimi "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->front.compareOp,
1790*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
1791*b7893ccfSSadaf Ebrahimi
1792*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1793*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1794*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->back.failOp", ParameterName::IndexVector{i}),
1795*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.failOp,
1796*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-failOp-parameter");
1797*b7893ccfSSadaf Ebrahimi
1798*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1799*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1800*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->back.passOp", ParameterName::IndexVector{i}),
1801*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.passOp,
1802*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-passOp-parameter");
1803*b7893ccfSSadaf Ebrahimi
1804*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1805*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1806*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->back.depthFailOp", ParameterName::IndexVector{i}),
1807*b7893ccfSSadaf Ebrahimi "VkStencilOp", AllVkStencilOpEnums, pCreateInfos[i].pDepthStencilState->back.depthFailOp,
1808*b7893ccfSSadaf Ebrahimi "VUID-VkStencilOpState-depthFailOp-parameter");
1809*b7893ccfSSadaf Ebrahimi
1810*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1811*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1812*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pDepthStencilState->back.compareOp", ParameterName::IndexVector{i}),
1813*b7893ccfSSadaf Ebrahimi "VkCompareOp", AllVkCompareOpEnums, pCreateInfos[i].pDepthStencilState->back.compareOp,
1814*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineDepthStencilStateCreateInfo-depthCompareOp-parameter");
1815*b7893ccfSSadaf Ebrahimi
1816*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pDepthStencilState->sType != VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO) {
1817*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1818*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidStructSType,
1819*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pDepthStencilState->sType must be "
1820*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO",
1821*b7893ccfSSadaf Ebrahimi i);
1822*b7893ccfSSadaf Ebrahimi }
1823*b7893ccfSSadaf Ebrahimi }
1824*b7893ccfSSadaf Ebrahimi
1825*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkPipelineColorBlendStateCreateInfo[] = {
1826*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT};
1827*b7893ccfSSadaf Ebrahimi
1828*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pColorBlendState != nullptr && uses_color_attachment) {
1829*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type("vkCreateGraphicsPipelines",
1830*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState", ParameterName::IndexVector{i}),
1831*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO",
1832*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState,
1833*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, false, kVUIDUndefined,
1834*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendStateCreateInfo-sType-sType");
1835*b7893ccfSSadaf Ebrahimi
1836*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
1837*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1838*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pNext", ParameterName::IndexVector{i}),
1839*b7893ccfSSadaf Ebrahimi "VkPipelineColorBlendAdvancedStateCreateInfoEXT", pCreateInfos[i].pColorBlendState->pNext,
1840*b7893ccfSSadaf Ebrahimi ARRAY_SIZE(allowed_structs_VkPipelineColorBlendStateCreateInfo),
1841*b7893ccfSSadaf Ebrahimi allowed_structs_VkPipelineColorBlendStateCreateInfo, GeneratedVulkanHeaderVersion,
1842*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendStateCreateInfo-pNext-pNext");
1843*b7893ccfSSadaf Ebrahimi
1844*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(
1845*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1846*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->flags", ParameterName::IndexVector{i}),
1847*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->flags, "VUID-VkPipelineColorBlendStateCreateInfo-flags-zerobitmask");
1848*b7893ccfSSadaf Ebrahimi
1849*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(
1850*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1851*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->logicOpEnable", ParameterName::IndexVector{i}),
1852*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->logicOpEnable);
1853*b7893ccfSSadaf Ebrahimi
1854*b7893ccfSSadaf Ebrahimi skip |= validate_array(
1855*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1856*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->attachmentCount", ParameterName::IndexVector{i}),
1857*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments", ParameterName::IndexVector{i}),
1858*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->attachmentCount, &pCreateInfos[i].pColorBlendState->pAttachments, false,
1859*b7893ccfSSadaf Ebrahimi true, kVUIDUndefined, kVUIDUndefined);
1860*b7893ccfSSadaf Ebrahimi
1861*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pColorBlendState->pAttachments != NULL) {
1862*b7893ccfSSadaf Ebrahimi for (uint32_t attachmentIndex = 0; attachmentIndex < pCreateInfos[i].pColorBlendState->attachmentCount;
1863*b7893ccfSSadaf Ebrahimi ++attachmentIndex) {
1864*b7893ccfSSadaf Ebrahimi skip |= validate_bool32("vkCreateGraphicsPipelines",
1865*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].blendEnable",
1866*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1867*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].blendEnable);
1868*b7893ccfSSadaf Ebrahimi
1869*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1870*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1871*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcColorBlendFactor",
1872*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1873*b7893ccfSSadaf Ebrahimi "VkBlendFactor", AllVkBlendFactorEnums,
1874*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcColorBlendFactor,
1875*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-srcColorBlendFactor-parameter");
1876*b7893ccfSSadaf Ebrahimi
1877*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1878*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1879*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstColorBlendFactor",
1880*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1881*b7893ccfSSadaf Ebrahimi "VkBlendFactor", AllVkBlendFactorEnums,
1882*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstColorBlendFactor,
1883*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-dstColorBlendFactor-parameter");
1884*b7893ccfSSadaf Ebrahimi
1885*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1886*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1887*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorBlendOp",
1888*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1889*b7893ccfSSadaf Ebrahimi "VkBlendOp", AllVkBlendOpEnums,
1890*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorBlendOp,
1891*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-colorBlendOp-parameter");
1892*b7893ccfSSadaf Ebrahimi
1893*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1894*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1895*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].srcAlphaBlendFactor",
1896*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1897*b7893ccfSSadaf Ebrahimi "VkBlendFactor", AllVkBlendFactorEnums,
1898*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].srcAlphaBlendFactor,
1899*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-srcAlphaBlendFactor-parameter");
1900*b7893ccfSSadaf Ebrahimi
1901*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1902*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1903*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].dstAlphaBlendFactor",
1904*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1905*b7893ccfSSadaf Ebrahimi "VkBlendFactor", AllVkBlendFactorEnums,
1906*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].dstAlphaBlendFactor,
1907*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-dstAlphaBlendFactor-parameter");
1908*b7893ccfSSadaf Ebrahimi
1909*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1910*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1911*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].alphaBlendOp",
1912*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1913*b7893ccfSSadaf Ebrahimi "VkBlendOp", AllVkBlendOpEnums,
1914*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].alphaBlendOp,
1915*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendAttachmentState-alphaBlendOp-parameter");
1916*b7893ccfSSadaf Ebrahimi
1917*b7893ccfSSadaf Ebrahimi skip |=
1918*b7893ccfSSadaf Ebrahimi validate_flags("vkCreateGraphicsPipelines",
1919*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->pAttachments[%i].colorWriteMask",
1920*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, attachmentIndex}),
1921*b7893ccfSSadaf Ebrahimi "VkColorComponentFlagBits", AllVkColorComponentFlagBits,
1922*b7893ccfSSadaf Ebrahimi pCreateInfos[i].pColorBlendState->pAttachments[attachmentIndex].colorWriteMask,
1923*b7893ccfSSadaf Ebrahimi kOptionalFlags, "VUID-VkPipelineColorBlendAttachmentState-colorWriteMask-parameter");
1924*b7893ccfSSadaf Ebrahimi }
1925*b7893ccfSSadaf Ebrahimi }
1926*b7893ccfSSadaf Ebrahimi
1927*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pColorBlendState->sType != VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO) {
1928*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1929*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidStructSType,
1930*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines: parameter pCreateInfos[%d].pColorBlendState->sType must be "
1931*b7893ccfSSadaf Ebrahimi "VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO",
1932*b7893ccfSSadaf Ebrahimi i);
1933*b7893ccfSSadaf Ebrahimi }
1934*b7893ccfSSadaf Ebrahimi
1935*b7893ccfSSadaf Ebrahimi // If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value
1936*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pColorBlendState->logicOpEnable == VK_TRUE) {
1937*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum(
1938*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines",
1939*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pColorBlendState->logicOp", ParameterName::IndexVector{i}), "VkLogicOp",
1940*b7893ccfSSadaf Ebrahimi AllVkLogicOpEnums, pCreateInfos[i].pColorBlendState->logicOp,
1941*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineColorBlendStateCreateInfo-logicOpEnable-00607");
1942*b7893ccfSSadaf Ebrahimi }
1943*b7893ccfSSadaf Ebrahimi }
1944*b7893ccfSSadaf Ebrahimi }
1945*b7893ccfSSadaf Ebrahimi
1946*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) {
1947*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].basePipelineIndex != -1) {
1948*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
1949*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1950*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-flags-00724",
1951*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineHandle, must be "
1952*b7893ccfSSadaf Ebrahimi "VK_NULL_HANDLE if pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag "
1953*b7893ccfSSadaf Ebrahimi "and pCreateInfos->basePipelineIndex is not -1.");
1954*b7893ccfSSadaf Ebrahimi }
1955*b7893ccfSSadaf Ebrahimi }
1956*b7893ccfSSadaf Ebrahimi
1957*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].basePipelineHandle != VK_NULL_HANDLE) {
1958*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].basePipelineIndex != -1) {
1959*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1960*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-flags-00725",
1961*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines parameter, pCreateInfos->basePipelineIndex, must be -1 if "
1962*b7893ccfSSadaf Ebrahimi "pCreateInfos->flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag and "
1963*b7893ccfSSadaf Ebrahimi "pCreateInfos->basePipelineHandle is not VK_NULL_HANDLE.");
1964*b7893ccfSSadaf Ebrahimi }
1965*b7893ccfSSadaf Ebrahimi }
1966*b7893ccfSSadaf Ebrahimi }
1967*b7893ccfSSadaf Ebrahimi
1968*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pRasterizationState) {
1969*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_nv_fill_rectangle) {
1970*b7893ccfSSadaf Ebrahimi if (pCreateInfos[i].pRasterizationState->polygonMode == VK_POLYGON_MODE_FILL_RECTANGLE_NV) {
1971*b7893ccfSSadaf Ebrahimi skip |=
1972*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1973*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01414",
1974*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines parameter, VkPolygonMode "
1975*b7893ccfSSadaf Ebrahimi "pCreateInfos->pRasterizationState->polygonMode cannot be VK_POLYGON_MODE_FILL_RECTANGLE_NV "
1976*b7893ccfSSadaf Ebrahimi "if the extension VK_NV_fill_rectangle is not enabled.");
1977*b7893ccfSSadaf Ebrahimi } else if ((pCreateInfos[i].pRasterizationState->polygonMode != VK_POLYGON_MODE_FILL) &&
1978*b7893ccfSSadaf Ebrahimi (physical_device_features.fillModeNonSolid == false)) {
1979*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1980*b7893ccfSSadaf Ebrahimi kVUID_PVError_DeviceFeature,
1981*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines parameter, VkPolygonMode "
1982*b7893ccfSSadaf Ebrahimi "pCreateInfos->pRasterizationState->polygonMode cannot be VK_POLYGON_MODE_POINT or "
1983*b7893ccfSSadaf Ebrahimi "VK_POLYGON_MODE_LINE if VkPhysicalDeviceFeatures->fillModeNonSolid is false.");
1984*b7893ccfSSadaf Ebrahimi }
1985*b7893ccfSSadaf Ebrahimi } else {
1986*b7893ccfSSadaf Ebrahimi if ((pCreateInfos[i].pRasterizationState->polygonMode != VK_POLYGON_MODE_FILL) &&
1987*b7893ccfSSadaf Ebrahimi (pCreateInfos[i].pRasterizationState->polygonMode != VK_POLYGON_MODE_FILL_RECTANGLE_NV) &&
1988*b7893ccfSSadaf Ebrahimi (physical_device_features.fillModeNonSolid == false)) {
1989*b7893ccfSSadaf Ebrahimi skip |=
1990*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
1991*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineRasterizationStateCreateInfo-polygonMode-01507",
1992*b7893ccfSSadaf Ebrahimi "vkCreateGraphicsPipelines parameter, VkPolygonMode "
1993*b7893ccfSSadaf Ebrahimi "pCreateInfos->pRasterizationState->polygonMode must be VK_POLYGON_MODE_FILL or "
1994*b7893ccfSSadaf Ebrahimi "VK_POLYGON_MODE_FILL_RECTANGLE_NV if VkPhysicalDeviceFeatures->fillModeNonSolid is false.");
1995*b7893ccfSSadaf Ebrahimi }
1996*b7893ccfSSadaf Ebrahimi }
1997*b7893ccfSSadaf Ebrahimi
1998*b7893ccfSSadaf Ebrahimi if (!has_dynamic_line_width && !physical_device_features.wideLines &&
1999*b7893ccfSSadaf Ebrahimi (pCreateInfos[i].pRasterizationState->lineWidth != 1.0f)) {
2000*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, 0,
2001*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pDynamicStates-00749",
2002*b7893ccfSSadaf Ebrahimi "The line width state is static (pCreateInfos[%" PRIu32
2003*b7893ccfSSadaf Ebrahimi "].pDynamicState->pDynamicStates does not contain VK_DYNAMIC_STATE_LINE_WIDTH) and "
2004*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceFeatures::wideLines is disabled, but pCreateInfos[%" PRIu32
2005*b7893ccfSSadaf Ebrahimi "].pRasterizationState->lineWidth (=%f) is not 1.0.",
2006*b7893ccfSSadaf Ebrahimi i, i, pCreateInfos[i].pRasterizationState->lineWidth);
2007*b7893ccfSSadaf Ebrahimi }
2008*b7893ccfSSadaf Ebrahimi }
2009*b7893ccfSSadaf Ebrahimi
2010*b7893ccfSSadaf Ebrahimi for (size_t j = 0; j < pCreateInfos[i].stageCount; j++) {
2011*b7893ccfSSadaf Ebrahimi skip |= validate_string("vkCreateGraphicsPipelines",
2012*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].pStages[%i].pName", ParameterName::IndexVector{i, j}),
2013*b7893ccfSSadaf Ebrahimi "VUID-VkGraphicsPipelineCreateInfo-pStages-parameter", pCreateInfos[i].pStages[j].pName);
2014*b7893ccfSSadaf Ebrahimi }
2015*b7893ccfSSadaf Ebrahimi }
2016*b7893ccfSSadaf Ebrahimi }
2017*b7893ccfSSadaf Ebrahimi
2018*b7893ccfSSadaf Ebrahimi return skip;
2019*b7893ccfSSadaf Ebrahimi }
2020*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateComputePipelines(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)2021*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache,
2022*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount,
2023*b7893ccfSSadaf Ebrahimi const VkComputePipelineCreateInfo *pCreateInfos,
2024*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2025*b7893ccfSSadaf Ebrahimi VkPipeline *pPipelines) {
2026*b7893ccfSSadaf Ebrahimi bool skip = false;
2027*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < createInfoCount; i++) {
2028*b7893ccfSSadaf Ebrahimi skip |= validate_string("vkCreateComputePipelines",
2029*b7893ccfSSadaf Ebrahimi ParameterName("pCreateInfos[%i].stage.pName", ParameterName::IndexVector{i}),
2030*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineShaderStageCreateInfo-pName-parameter", pCreateInfos[i].stage.pName);
2031*b7893ccfSSadaf Ebrahimi auto feedback_struct = lvl_find_in_chain<VkPipelineCreationFeedbackCreateInfoEXT>(pCreateInfos[i].pNext);
2032*b7893ccfSSadaf Ebrahimi if ((feedback_struct != nullptr) && (feedback_struct->pipelineStageCreationFeedbackCount != 1)) {
2033*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
2034*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02669",
2035*b7893ccfSSadaf Ebrahimi "vkCreateComputePipelines(): in pCreateInfo[%" PRIu32
2036*b7893ccfSSadaf Ebrahimi "], VkPipelineCreationFeedbackEXT::pipelineStageCreationFeedbackCount must equal 1, found %" PRIu32 ".",
2037*b7893ccfSSadaf Ebrahimi i, feedback_struct->pipelineStageCreationFeedbackCount);
2038*b7893ccfSSadaf Ebrahimi }
2039*b7893ccfSSadaf Ebrahimi }
2040*b7893ccfSSadaf Ebrahimi return skip;
2041*b7893ccfSSadaf Ebrahimi }
2042*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateSampler(VkDevice device,const VkSamplerCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSampler * pSampler)2043*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
2044*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
2045*b7893ccfSSadaf Ebrahimi bool skip = false;
2046*b7893ccfSSadaf Ebrahimi
2047*b7893ccfSSadaf Ebrahimi if (pCreateInfo != nullptr) {
2048*b7893ccfSSadaf Ebrahimi const auto &features = physical_device_features;
2049*b7893ccfSSadaf Ebrahimi const auto &limits = device_limits;
2050*b7893ccfSSadaf Ebrahimi
2051*b7893ccfSSadaf Ebrahimi if (pCreateInfo->anisotropyEnable == VK_TRUE) {
2052*b7893ccfSSadaf Ebrahimi if (!in_inclusive_range(pCreateInfo->maxAnisotropy, 1.0F, limits.maxSamplerAnisotropy)) {
2053*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2054*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-anisotropyEnable-01071",
2055*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): value of %s must be in range [1.0, %f] %s, but %f found.",
2056*b7893ccfSSadaf Ebrahimi "pCreateInfo->maxAnisotropy", limits.maxSamplerAnisotropy,
2057*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceLimits::maxSamplerAnistropy", pCreateInfo->maxAnisotropy);
2058*b7893ccfSSadaf Ebrahimi }
2059*b7893ccfSSadaf Ebrahimi
2060*b7893ccfSSadaf Ebrahimi // Anistropy cannot be enabled in sampler unless enabled as a feature
2061*b7893ccfSSadaf Ebrahimi if (features.samplerAnisotropy == VK_FALSE) {
2062*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2063*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-anisotropyEnable-01070",
2064*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): Anisotropic sampling feature is not enabled, %s must be VK_FALSE.",
2065*b7893ccfSSadaf Ebrahimi "pCreateInfo->anisotropyEnable");
2066*b7893ccfSSadaf Ebrahimi }
2067*b7893ccfSSadaf Ebrahimi }
2068*b7893ccfSSadaf Ebrahimi
2069*b7893ccfSSadaf Ebrahimi if (pCreateInfo->unnormalizedCoordinates == VK_TRUE) {
2070*b7893ccfSSadaf Ebrahimi if (pCreateInfo->minFilter != pCreateInfo->magFilter) {
2071*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2072*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01072",
2073*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
2074*b7893ccfSSadaf Ebrahimi "pCreateInfo->minFilter (%s) and pCreateInfo->magFilter (%s) must be equal.",
2075*b7893ccfSSadaf Ebrahimi string_VkFilter(pCreateInfo->minFilter), string_VkFilter(pCreateInfo->magFilter));
2076*b7893ccfSSadaf Ebrahimi }
2077*b7893ccfSSadaf Ebrahimi if (pCreateInfo->mipmapMode != VK_SAMPLER_MIPMAP_MODE_NEAREST) {
2078*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2079*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01073",
2080*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
2081*b7893ccfSSadaf Ebrahimi "pCreateInfo->mipmapMode (%s) must be VK_SAMPLER_MIPMAP_MODE_NEAREST.",
2082*b7893ccfSSadaf Ebrahimi string_VkSamplerMipmapMode(pCreateInfo->mipmapMode));
2083*b7893ccfSSadaf Ebrahimi }
2084*b7893ccfSSadaf Ebrahimi if (pCreateInfo->minLod != 0.0f || pCreateInfo->maxLod != 0.0f) {
2085*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2086*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01074",
2087*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
2088*b7893ccfSSadaf Ebrahimi "pCreateInfo->minLod (%f) and pCreateInfo->maxLod (%f) must both be zero.",
2089*b7893ccfSSadaf Ebrahimi pCreateInfo->minLod, pCreateInfo->maxLod);
2090*b7893ccfSSadaf Ebrahimi }
2091*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
2092*b7893ccfSSadaf Ebrahimi pCreateInfo->addressModeU != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
2093*b7893ccfSSadaf Ebrahimi (pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE &&
2094*b7893ccfSSadaf Ebrahimi pCreateInfo->addressModeV != VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
2095*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2096*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01075",
2097*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): when pCreateInfo->unnormalizedCoordinates is VK_TRUE, "
2098*b7893ccfSSadaf Ebrahimi "pCreateInfo->addressModeU (%s) and pCreateInfo->addressModeV (%s) must both be "
2099*b7893ccfSSadaf Ebrahimi "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER.",
2100*b7893ccfSSadaf Ebrahimi string_VkSamplerAddressMode(pCreateInfo->addressModeU),
2101*b7893ccfSSadaf Ebrahimi string_VkSamplerAddressMode(pCreateInfo->addressModeV));
2102*b7893ccfSSadaf Ebrahimi }
2103*b7893ccfSSadaf Ebrahimi if (pCreateInfo->anisotropyEnable == VK_TRUE) {
2104*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2105*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01076",
2106*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): pCreateInfo->anisotropyEnable and pCreateInfo->unnormalizedCoordinates must "
2107*b7893ccfSSadaf Ebrahimi "not both be VK_TRUE.");
2108*b7893ccfSSadaf Ebrahimi }
2109*b7893ccfSSadaf Ebrahimi if (pCreateInfo->compareEnable == VK_TRUE) {
2110*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2111*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-unnormalizedCoordinates-01077",
2112*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): pCreateInfo->compareEnable and pCreateInfo->unnormalizedCoordinates must "
2113*b7893ccfSSadaf Ebrahimi "not both be VK_TRUE.");
2114*b7893ccfSSadaf Ebrahimi }
2115*b7893ccfSSadaf Ebrahimi }
2116*b7893ccfSSadaf Ebrahimi
2117*b7893ccfSSadaf Ebrahimi // If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value
2118*b7893ccfSSadaf Ebrahimi if (pCreateInfo->compareEnable == VK_TRUE) {
2119*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum("vkCreateSampler", "pCreateInfo->compareOp", "VkCompareOp", AllVkCompareOpEnums,
2120*b7893ccfSSadaf Ebrahimi pCreateInfo->compareOp, "VUID-VkSamplerCreateInfo-compareEnable-01080");
2121*b7893ccfSSadaf Ebrahimi }
2122*b7893ccfSSadaf Ebrahimi
2123*b7893ccfSSadaf Ebrahimi // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a
2124*b7893ccfSSadaf Ebrahimi // valid VkBorderColor value
2125*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
2126*b7893ccfSSadaf Ebrahimi (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER) ||
2127*b7893ccfSSadaf Ebrahimi (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER)) {
2128*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum("vkCreateSampler", "pCreateInfo->borderColor", "VkBorderColor", AllVkBorderColorEnums,
2129*b7893ccfSSadaf Ebrahimi pCreateInfo->borderColor, "VUID-VkSamplerCreateInfo-addressModeU-01078");
2130*b7893ccfSSadaf Ebrahimi }
2131*b7893ccfSSadaf Ebrahimi
2132*b7893ccfSSadaf Ebrahimi // If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, the
2133*b7893ccfSSadaf Ebrahimi // VK_KHR_sampler_mirror_clamp_to_edge extension must be enabled
2134*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_khr_sampler_mirror_clamp_to_edge &&
2135*b7893ccfSSadaf Ebrahimi ((pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
2136*b7893ccfSSadaf Ebrahimi (pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) ||
2137*b7893ccfSSadaf Ebrahimi (pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE))) {
2138*b7893ccfSSadaf Ebrahimi skip |=
2139*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2140*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-addressModeU-01079",
2141*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): A VkSamplerAddressMode value is set to VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE "
2142*b7893ccfSSadaf Ebrahimi "but the VK_KHR_sampler_mirror_clamp_to_edge extension has not been enabled.");
2143*b7893ccfSSadaf Ebrahimi }
2144*b7893ccfSSadaf Ebrahimi
2145*b7893ccfSSadaf Ebrahimi // Checks for the IMG cubic filtering extension
2146*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_img_filter_cubic) {
2147*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->anisotropyEnable == VK_TRUE) &&
2148*b7893ccfSSadaf Ebrahimi ((pCreateInfo->minFilter == VK_FILTER_CUBIC_IMG) || (pCreateInfo->magFilter == VK_FILTER_CUBIC_IMG))) {
2149*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2150*b7893ccfSSadaf Ebrahimi "VUID-VkSamplerCreateInfo-magFilter-01081",
2151*b7893ccfSSadaf Ebrahimi "vkCreateSampler(): Anisotropic sampling must not be VK_TRUE when either minFilter or magFilter "
2152*b7893ccfSSadaf Ebrahimi "are VK_FILTER_CUBIC_IMG.");
2153*b7893ccfSSadaf Ebrahimi }
2154*b7893ccfSSadaf Ebrahimi }
2155*b7893ccfSSadaf Ebrahimi }
2156*b7893ccfSSadaf Ebrahimi
2157*b7893ccfSSadaf Ebrahimi return skip;
2158*b7893ccfSSadaf Ebrahimi }
2159*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device,const VkDescriptorSetLayoutCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorSetLayout * pSetLayout)2160*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateDescriptorSetLayout(VkDevice device,
2161*b7893ccfSSadaf Ebrahimi const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
2162*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2163*b7893ccfSSadaf Ebrahimi VkDescriptorSetLayout *pSetLayout) {
2164*b7893ccfSSadaf Ebrahimi bool skip = false;
2165*b7893ccfSSadaf Ebrahimi
2166*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2167*b7893ccfSSadaf Ebrahimi if ((pCreateInfo != nullptr) && (pCreateInfo->pBindings != nullptr)) {
2168*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->bindingCount; ++i) {
2169*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pBindings[i].descriptorCount != 0) {
2170*b7893ccfSSadaf Ebrahimi // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount
2171*b7893ccfSSadaf Ebrahimi // is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount
2172*b7893ccfSSadaf Ebrahimi // valid VkSampler handles
2173*b7893ccfSSadaf Ebrahimi if (((pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2174*b7893ccfSSadaf Ebrahimi (pCreateInfo->pBindings[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) &&
2175*b7893ccfSSadaf Ebrahimi (pCreateInfo->pBindings[i].pImmutableSamplers != nullptr)) {
2176*b7893ccfSSadaf Ebrahimi for (uint32_t descriptor_index = 0; descriptor_index < pCreateInfo->pBindings[i].descriptorCount;
2177*b7893ccfSSadaf Ebrahimi ++descriptor_index) {
2178*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pBindings[i].pImmutableSamplers[descriptor_index] == VK_NULL_HANDLE) {
2179*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2180*b7893ccfSSadaf Ebrahimi kVUID_PVError_RequiredParameter,
2181*b7893ccfSSadaf Ebrahimi "vkCreateDescriptorSetLayout: required parameter "
2182*b7893ccfSSadaf Ebrahimi "pCreateInfo->pBindings[%d].pImmutableSamplers[%d] specified as VK_NULL_HANDLE",
2183*b7893ccfSSadaf Ebrahimi i, descriptor_index);
2184*b7893ccfSSadaf Ebrahimi }
2185*b7893ccfSSadaf Ebrahimi }
2186*b7893ccfSSadaf Ebrahimi }
2187*b7893ccfSSadaf Ebrahimi
2188*b7893ccfSSadaf Ebrahimi // If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values
2189*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->pBindings[i].stageFlags != 0) &&
2190*b7893ccfSSadaf Ebrahimi ((pCreateInfo->pBindings[i].stageFlags & (~AllVkShaderStageFlagBits)) != 0)) {
2191*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2192*b7893ccfSSadaf Ebrahimi "VUID-VkDescriptorSetLayoutBinding-descriptorCount-00283",
2193*b7893ccfSSadaf Ebrahimi "vkCreateDescriptorSetLayout(): if pCreateInfo->pBindings[%d].descriptorCount is not 0, "
2194*b7893ccfSSadaf Ebrahimi "pCreateInfo->pBindings[%d].stageFlags must be a valid combination of VkShaderStageFlagBits "
2195*b7893ccfSSadaf Ebrahimi "values.",
2196*b7893ccfSSadaf Ebrahimi i, i);
2197*b7893ccfSSadaf Ebrahimi }
2198*b7893ccfSSadaf Ebrahimi }
2199*b7893ccfSSadaf Ebrahimi }
2200*b7893ccfSSadaf Ebrahimi }
2201*b7893ccfSSadaf Ebrahimi return skip;
2202*b7893ccfSSadaf Ebrahimi }
2203*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateFreeDescriptorSets(VkDevice device,VkDescriptorPool descriptorPool,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets)2204*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateFreeDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool,
2205*b7893ccfSSadaf Ebrahimi uint32_t descriptorSetCount,
2206*b7893ccfSSadaf Ebrahimi const VkDescriptorSet *pDescriptorSets) {
2207*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2208*b7893ccfSSadaf Ebrahimi // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
2209*b7893ccfSSadaf Ebrahimi // validate_array()
2210*b7893ccfSSadaf Ebrahimi return validate_array("vkFreeDescriptorSets", "descriptorSetCount", "pDescriptorSets", descriptorSetCount, &pDescriptorSets,
2211*b7893ccfSSadaf Ebrahimi true, true, kVUIDUndefined, kVUIDUndefined);
2212*b7893ccfSSadaf Ebrahimi }
2213*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateUpdateDescriptorSets(VkDevice device,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites,uint32_t descriptorCopyCount,const VkCopyDescriptorSet * pDescriptorCopies)2214*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateUpdateDescriptorSets(VkDevice device, uint32_t descriptorWriteCount,
2215*b7893ccfSSadaf Ebrahimi const VkWriteDescriptorSet *pDescriptorWrites,
2216*b7893ccfSSadaf Ebrahimi uint32_t descriptorCopyCount,
2217*b7893ccfSSadaf Ebrahimi const VkCopyDescriptorSet *pDescriptorCopies) {
2218*b7893ccfSSadaf Ebrahimi bool skip = false;
2219*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2220*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites != NULL) {
2221*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < descriptorWriteCount; ++i) {
2222*b7893ccfSSadaf Ebrahimi // descriptorCount must be greater than 0
2223*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].descriptorCount == 0) {
2224*b7893ccfSSadaf Ebrahimi skip |=
2225*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2226*b7893ccfSSadaf Ebrahimi "VUID-VkWriteDescriptorSet-descriptorCount-arraylength",
2227*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): parameter pDescriptorWrites[%d].descriptorCount must be greater than 0.", i);
2228*b7893ccfSSadaf Ebrahimi }
2229*b7893ccfSSadaf Ebrahimi
2230*b7893ccfSSadaf Ebrahimi // dstSet must be a valid VkDescriptorSet handle
2231*b7893ccfSSadaf Ebrahimi skip |= validate_required_handle("vkUpdateDescriptorSets",
2232*b7893ccfSSadaf Ebrahimi ParameterName("pDescriptorWrites[%i].dstSet", ParameterName::IndexVector{i}),
2233*b7893ccfSSadaf Ebrahimi pDescriptorWrites[i].dstSet);
2234*b7893ccfSSadaf Ebrahimi
2235*b7893ccfSSadaf Ebrahimi if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2236*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
2237*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2238*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
2239*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
2240*b7893ccfSSadaf Ebrahimi // If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2241*b7893ccfSSadaf Ebrahimi // VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
2242*b7893ccfSSadaf Ebrahimi // pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures
2243*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].pImageInfo == nullptr) {
2244*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2245*b7893ccfSSadaf Ebrahimi "VUID-VkWriteDescriptorSet-descriptorType-00322",
2246*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2247*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "
2248*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or "
2249*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pDescriptorWrites[%d].pImageInfo must not be NULL.",
2250*b7893ccfSSadaf Ebrahimi i, i);
2251*b7893ccfSSadaf Ebrahimi } else if (pDescriptorWrites[i].descriptorType != VK_DESCRIPTOR_TYPE_SAMPLER) {
2252*b7893ccfSSadaf Ebrahimi // If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
2253*b7893ccfSSadaf Ebrahimi // VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout
2254*b7893ccfSSadaf Ebrahimi // members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively
2255*b7893ccfSSadaf Ebrahimi for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2256*b7893ccfSSadaf Ebrahimi ++descriptor_index) {
2257*b7893ccfSSadaf Ebrahimi skip |= validate_required_handle("vkUpdateDescriptorSets",
2258*b7893ccfSSadaf Ebrahimi ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageView",
2259*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, descriptor_index}),
2260*b7893ccfSSadaf Ebrahimi pDescriptorWrites[i].pImageInfo[descriptor_index].imageView);
2261*b7893ccfSSadaf Ebrahimi skip |= validate_ranged_enum("vkUpdateDescriptorSets",
2262*b7893ccfSSadaf Ebrahimi ParameterName("pDescriptorWrites[%i].pImageInfo[%i].imageLayout",
2263*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, descriptor_index}),
2264*b7893ccfSSadaf Ebrahimi "VkImageLayout", AllVkImageLayoutEnums,
2265*b7893ccfSSadaf Ebrahimi pDescriptorWrites[i].pImageInfo[descriptor_index].imageLayout, kVUIDUndefined);
2266*b7893ccfSSadaf Ebrahimi }
2267*b7893ccfSSadaf Ebrahimi }
2268*b7893ccfSSadaf Ebrahimi } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2269*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2270*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
2271*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
2272*b7893ccfSSadaf Ebrahimi // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
2273*b7893ccfSSadaf Ebrahimi // VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a
2274*b7893ccfSSadaf Ebrahimi // pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures
2275*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].pBufferInfo == nullptr) {
2276*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2277*b7893ccfSSadaf Ebrahimi "VUID-VkWriteDescriptorSet-descriptorType-00324",
2278*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2279*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "
2280*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "
2281*b7893ccfSSadaf Ebrahimi "pDescriptorWrites[%d].pBufferInfo must not be NULL.",
2282*b7893ccfSSadaf Ebrahimi i, i);
2283*b7893ccfSSadaf Ebrahimi } else {
2284*b7893ccfSSadaf Ebrahimi for (uint32_t descriptorIndex = 0; descriptorIndex < pDescriptorWrites[i].descriptorCount; ++descriptorIndex) {
2285*b7893ccfSSadaf Ebrahimi skip |= validate_required_handle("vkUpdateDescriptorSets",
2286*b7893ccfSSadaf Ebrahimi ParameterName("pDescriptorWrites[%i].pBufferInfo[%i].buffer",
2287*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, descriptorIndex}),
2288*b7893ccfSSadaf Ebrahimi pDescriptorWrites[i].pBufferInfo[descriptorIndex].buffer);
2289*b7893ccfSSadaf Ebrahimi }
2290*b7893ccfSSadaf Ebrahimi }
2291*b7893ccfSSadaf Ebrahimi } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
2292*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
2293*b7893ccfSSadaf Ebrahimi // If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
2294*b7893ccfSSadaf Ebrahimi // pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles
2295*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].pTexelBufferView == nullptr) {
2296*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2297*b7893ccfSSadaf Ebrahimi "VUID-VkWriteDescriptorSet-descriptorType-00323",
2298*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): if pDescriptorWrites[%d].descriptorType is "
2299*b7893ccfSSadaf Ebrahimi "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "
2300*b7893ccfSSadaf Ebrahimi "pDescriptorWrites[%d].pTexelBufferView must not be NULL.",
2301*b7893ccfSSadaf Ebrahimi i, i);
2302*b7893ccfSSadaf Ebrahimi } else {
2303*b7893ccfSSadaf Ebrahimi for (uint32_t descriptor_index = 0; descriptor_index < pDescriptorWrites[i].descriptorCount;
2304*b7893ccfSSadaf Ebrahimi ++descriptor_index) {
2305*b7893ccfSSadaf Ebrahimi skip |= validate_required_handle("vkUpdateDescriptorSets",
2306*b7893ccfSSadaf Ebrahimi ParameterName("pDescriptorWrites[%i].pTexelBufferView[%i]",
2307*b7893ccfSSadaf Ebrahimi ParameterName::IndexVector{i, descriptor_index}),
2308*b7893ccfSSadaf Ebrahimi pDescriptorWrites[i].pTexelBufferView[descriptor_index]);
2309*b7893ccfSSadaf Ebrahimi }
2310*b7893ccfSSadaf Ebrahimi }
2311*b7893ccfSSadaf Ebrahimi }
2312*b7893ccfSSadaf Ebrahimi
2313*b7893ccfSSadaf Ebrahimi if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
2314*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)) {
2315*b7893ccfSSadaf Ebrahimi VkDeviceSize uniformAlignment = device_limits.minUniformBufferOffsetAlignment;
2316*b7893ccfSSadaf Ebrahimi for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2317*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].pBufferInfo != NULL) {
2318*b7893ccfSSadaf Ebrahimi if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment) != 0) {
2319*b7893ccfSSadaf Ebrahimi skip |=
2320*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
2321*b7893ccfSSadaf Ebrahimi 0, "VUID-VkWriteDescriptorSet-descriptorType-00327",
2322*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2323*b7893ccfSSadaf Ebrahimi ") must be a multiple of device limit minUniformBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2324*b7893ccfSSadaf Ebrahimi i, j, pDescriptorWrites[i].pBufferInfo[j].offset, uniformAlignment);
2325*b7893ccfSSadaf Ebrahimi }
2326*b7893ccfSSadaf Ebrahimi }
2327*b7893ccfSSadaf Ebrahimi }
2328*b7893ccfSSadaf Ebrahimi } else if ((pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
2329*b7893ccfSSadaf Ebrahimi (pDescriptorWrites[i].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
2330*b7893ccfSSadaf Ebrahimi VkDeviceSize storageAlignment = device_limits.minStorageBufferOffsetAlignment;
2331*b7893ccfSSadaf Ebrahimi for (uint32_t j = 0; j < pDescriptorWrites[i].descriptorCount; j++) {
2332*b7893ccfSSadaf Ebrahimi if (pDescriptorWrites[i].pBufferInfo != NULL) {
2333*b7893ccfSSadaf Ebrahimi if (SafeModulo(pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment) != 0) {
2334*b7893ccfSSadaf Ebrahimi skip |=
2335*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
2336*b7893ccfSSadaf Ebrahimi 0, "VUID-VkWriteDescriptorSet-descriptorType-00328",
2337*b7893ccfSSadaf Ebrahimi "vkUpdateDescriptorSets(): pDescriptorWrites[%d].pBufferInfo[%d].offset (0x%" PRIxLEAST64
2338*b7893ccfSSadaf Ebrahimi ") must be a multiple of device limit minStorageBufferOffsetAlignment 0x%" PRIxLEAST64 ".",
2339*b7893ccfSSadaf Ebrahimi i, j, pDescriptorWrites[i].pBufferInfo[j].offset, storageAlignment);
2340*b7893ccfSSadaf Ebrahimi }
2341*b7893ccfSSadaf Ebrahimi }
2342*b7893ccfSSadaf Ebrahimi }
2343*b7893ccfSSadaf Ebrahimi }
2344*b7893ccfSSadaf Ebrahimi }
2345*b7893ccfSSadaf Ebrahimi }
2346*b7893ccfSSadaf Ebrahimi return skip;
2347*b7893ccfSSadaf Ebrahimi }
2348*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateRenderPass(VkDevice device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)2349*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
2350*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2351*b7893ccfSSadaf Ebrahimi VkRenderPass *pRenderPass) {
2352*b7893ccfSSadaf Ebrahimi return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_1);
2353*b7893ccfSSadaf Ebrahimi }
2354*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateRenderPass2KHR(VkDevice device,const VkRenderPassCreateInfo2KHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)2355*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
2356*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2357*b7893ccfSSadaf Ebrahimi VkRenderPass *pRenderPass) {
2358*b7893ccfSSadaf Ebrahimi return CreateRenderPassGeneric(device, pCreateInfo, pAllocator, pRenderPass, RENDER_PASS_VERSION_2);
2359*b7893ccfSSadaf Ebrahimi }
2360*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateFreeCommandBuffers(VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)2361*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateFreeCommandBuffers(VkDevice device, VkCommandPool commandPool,
2362*b7893ccfSSadaf Ebrahimi uint32_t commandBufferCount,
2363*b7893ccfSSadaf Ebrahimi const VkCommandBuffer *pCommandBuffers) {
2364*b7893ccfSSadaf Ebrahimi bool skip = false;
2365*b7893ccfSSadaf Ebrahimi
2366*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2367*b7893ccfSSadaf Ebrahimi // This is an array of handles, where the elements are allowed to be VK_NULL_HANDLE, and does not require any validation beyond
2368*b7893ccfSSadaf Ebrahimi // validate_array()
2369*b7893ccfSSadaf Ebrahimi skip |= validate_array("vkFreeCommandBuffers", "commandBufferCount", "pCommandBuffers", commandBufferCount, &pCommandBuffers,
2370*b7893ccfSSadaf Ebrahimi true, true, kVUIDUndefined, kVUIDUndefined);
2371*b7893ccfSSadaf Ebrahimi return skip;
2372*b7893ccfSSadaf Ebrahimi }
2373*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)2374*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateBeginCommandBuffer(VkCommandBuffer commandBuffer,
2375*b7893ccfSSadaf Ebrahimi const VkCommandBufferBeginInfo *pBeginInfo) {
2376*b7893ccfSSadaf Ebrahimi bool skip = false;
2377*b7893ccfSSadaf Ebrahimi
2378*b7893ccfSSadaf Ebrahimi // VkCommandBufferInheritanceInfo validation, due to a 'noautovalidity' of pBeginInfo->pInheritanceInfo in vkBeginCommandBuffer
2379*b7893ccfSSadaf Ebrahimi const char *cmd_name = "vkBeginCommandBuffer";
2380*b7893ccfSSadaf Ebrahimi const VkCommandBufferInheritanceInfo *pInfo = pBeginInfo->pInheritanceInfo;
2381*b7893ccfSSadaf Ebrahimi
2382*b7893ccfSSadaf Ebrahimi // Implicit VUs
2383*b7893ccfSSadaf Ebrahimi // validate only sType here; pointer has to be validated in core_validation
2384*b7893ccfSSadaf Ebrahimi const bool kNotRequired = false;
2385*b7893ccfSSadaf Ebrahimi const char *kNoVUID = nullptr;
2386*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type(cmd_name, "pBeginInfo->pInheritanceInfo", "VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO",
2387*b7893ccfSSadaf Ebrahimi pInfo, VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, kNotRequired, kNoVUID,
2388*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceInfo-sType-sType");
2389*b7893ccfSSadaf Ebrahimi
2390*b7893ccfSSadaf Ebrahimi if (pInfo) {
2391*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkCommandBufferInheritanceInfo[] = {
2392*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT};
2393*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext(
2394*b7893ccfSSadaf Ebrahimi cmd_name, "pBeginInfo->pInheritanceInfo->pNext", "VkCommandBufferInheritanceConditionalRenderingInfoEXT", pInfo->pNext,
2395*b7893ccfSSadaf Ebrahimi ARRAY_SIZE(allowed_structs_VkCommandBufferInheritanceInfo), allowed_structs_VkCommandBufferInheritanceInfo,
2396*b7893ccfSSadaf Ebrahimi GeneratedVulkanHeaderVersion, "VUID-VkCommandBufferInheritanceInfo-pNext-pNext");
2397*b7893ccfSSadaf Ebrahimi
2398*b7893ccfSSadaf Ebrahimi skip |= validate_bool32(cmd_name, "pBeginInfo->pInheritanceInfo->occlusionQueryEnable", pInfo->occlusionQueryEnable);
2399*b7893ccfSSadaf Ebrahimi
2400*b7893ccfSSadaf Ebrahimi // Explicit VUs
2401*b7893ccfSSadaf Ebrahimi if (!physical_device_features.inheritedQueries && pInfo->occlusionQueryEnable == VK_TRUE) {
2402*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2403*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2404*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-VkCommandBufferInheritanceInfo-occlusionQueryEnable-00056",
2405*b7893ccfSSadaf Ebrahimi "%s: Inherited queries feature is disabled, but pBeginInfo->pInheritanceInfo->occlusionQueryEnable is VK_TRUE.",
2406*b7893ccfSSadaf Ebrahimi cmd_name);
2407*b7893ccfSSadaf Ebrahimi }
2408*b7893ccfSSadaf Ebrahimi
2409*b7893ccfSSadaf Ebrahimi if (physical_device_features.inheritedQueries) {
2410*b7893ccfSSadaf Ebrahimi skip |= validate_flags(cmd_name, "pBeginInfo->pInheritanceInfo->queryFlags", "VkQueryControlFlagBits",
2411*b7893ccfSSadaf Ebrahimi AllVkQueryControlFlagBits, pInfo->queryFlags, kOptionalFlags,
2412*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceInfo-queryFlags-00057");
2413*b7893ccfSSadaf Ebrahimi } else { // !inheritedQueries
2414*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(cmd_name, "pBeginInfo->pInheritanceInfo->queryFlags", pInfo->queryFlags,
2415*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceInfo-queryFlags-02788");
2416*b7893ccfSSadaf Ebrahimi }
2417*b7893ccfSSadaf Ebrahimi
2418*b7893ccfSSadaf Ebrahimi if (physical_device_features.pipelineStatisticsQuery) {
2419*b7893ccfSSadaf Ebrahimi skip |= validate_flags(cmd_name, "pBeginInfo->pInheritanceInfo->pipelineStatistics", "VkQueryPipelineStatisticFlagBits",
2420*b7893ccfSSadaf Ebrahimi AllVkQueryPipelineStatisticFlagBits, pInfo->pipelineStatistics, kOptionalFlags,
2421*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-02789");
2422*b7893ccfSSadaf Ebrahimi } else { // !pipelineStatisticsQuery
2423*b7893ccfSSadaf Ebrahimi skip |= validate_reserved_flags(cmd_name, "pBeginInfo->pInheritanceInfo->pipelineStatistics", pInfo->pipelineStatistics,
2424*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceInfo-pipelineStatistics-00058");
2425*b7893ccfSSadaf Ebrahimi }
2426*b7893ccfSSadaf Ebrahimi
2427*b7893ccfSSadaf Ebrahimi const auto *conditional_rendering = lvl_find_in_chain<VkCommandBufferInheritanceConditionalRenderingInfoEXT>(pInfo->pNext);
2428*b7893ccfSSadaf Ebrahimi if (conditional_rendering) {
2429*b7893ccfSSadaf Ebrahimi const auto *cr_features =
2430*b7893ccfSSadaf Ebrahimi lvl_find_in_chain<VkPhysicalDeviceConditionalRenderingFeaturesEXT>(physical_device_features2.pNext);
2431*b7893ccfSSadaf Ebrahimi const auto inherited_conditional_rendering = cr_features && cr_features->inheritedConditionalRendering;
2432*b7893ccfSSadaf Ebrahimi if (!inherited_conditional_rendering && conditional_rendering->conditionalRenderingEnable == VK_TRUE) {
2433*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2434*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2435*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer),
2436*b7893ccfSSadaf Ebrahimi "VUID-VkCommandBufferInheritanceConditionalRenderingInfoEXT-conditionalRenderingEnable-01977",
2437*b7893ccfSSadaf Ebrahimi "vkBeginCommandBuffer: Inherited conditional rendering is disabled, but "
2438*b7893ccfSSadaf Ebrahimi "pBeginInfo->pInheritanceInfo->pNext<VkCommandBufferInheritanceConditionalRenderingInfoEXT> is VK_TRUE.");
2439*b7893ccfSSadaf Ebrahimi }
2440*b7893ccfSSadaf Ebrahimi }
2441*b7893ccfSSadaf Ebrahimi }
2442*b7893ccfSSadaf Ebrahimi
2443*b7893ccfSSadaf Ebrahimi return skip;
2444*b7893ccfSSadaf Ebrahimi }
2445*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)2446*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetViewport(VkCommandBuffer commandBuffer, uint32_t firstViewport,
2447*b7893ccfSSadaf Ebrahimi uint32_t viewportCount, const VkViewport *pViewports) {
2448*b7893ccfSSadaf Ebrahimi bool skip = false;
2449*b7893ccfSSadaf Ebrahimi
2450*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiViewport) {
2451*b7893ccfSSadaf Ebrahimi if (firstViewport != 0) {
2452*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2453*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01224",
2454*b7893ccfSSadaf Ebrahimi "vkCmdSetViewport: The multiViewport feature is disabled, but firstViewport (=%" PRIu32 ") is not 0.",
2455*b7893ccfSSadaf Ebrahimi firstViewport);
2456*b7893ccfSSadaf Ebrahimi }
2457*b7893ccfSSadaf Ebrahimi if (viewportCount > 1) {
2458*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2459*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-viewportCount-01225",
2460*b7893ccfSSadaf Ebrahimi "vkCmdSetViewport: The multiViewport feature is disabled, but viewportCount (=%" PRIu32 ") is not 1.",
2461*b7893ccfSSadaf Ebrahimi viewportCount);
2462*b7893ccfSSadaf Ebrahimi }
2463*b7893ccfSSadaf Ebrahimi } else { // multiViewport enabled
2464*b7893ccfSSadaf Ebrahimi const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
2465*b7893ccfSSadaf Ebrahimi if (sum > device_limits.maxViewports) {
2466*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2467*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewport-firstViewport-01223",
2468*b7893ccfSSadaf Ebrahimi "vkCmdSetViewport: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
2469*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
2470*b7893ccfSSadaf Ebrahimi firstViewport, viewportCount, sum, device_limits.maxViewports);
2471*b7893ccfSSadaf Ebrahimi }
2472*b7893ccfSSadaf Ebrahimi }
2473*b7893ccfSSadaf Ebrahimi
2474*b7893ccfSSadaf Ebrahimi if (pViewports) {
2475*b7893ccfSSadaf Ebrahimi for (uint32_t viewport_i = 0; viewport_i < viewportCount; ++viewport_i) {
2476*b7893ccfSSadaf Ebrahimi const auto &viewport = pViewports[viewport_i]; // will crash on invalid ptr
2477*b7893ccfSSadaf Ebrahimi const char *fn_name = "vkCmdSetViewport";
2478*b7893ccfSSadaf Ebrahimi skip |= manual_PreCallValidateViewport(viewport, fn_name,
2479*b7893ccfSSadaf Ebrahimi ParameterName("pViewports[%i]", ParameterName::IndexVector{viewport_i}),
2480*b7893ccfSSadaf Ebrahimi VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, HandleToUint64(commandBuffer));
2481*b7893ccfSSadaf Ebrahimi }
2482*b7893ccfSSadaf Ebrahimi }
2483*b7893ccfSSadaf Ebrahimi
2484*b7893ccfSSadaf Ebrahimi return skip;
2485*b7893ccfSSadaf Ebrahimi }
2486*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)2487*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetScissor(VkCommandBuffer commandBuffer, uint32_t firstScissor,
2488*b7893ccfSSadaf Ebrahimi uint32_t scissorCount, const VkRect2D *pScissors) {
2489*b7893ccfSSadaf Ebrahimi bool skip = false;
2490*b7893ccfSSadaf Ebrahimi
2491*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiViewport) {
2492*b7893ccfSSadaf Ebrahimi if (firstScissor != 0) {
2493*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2494*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00593",
2495*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: The multiViewport feature is disabled, but firstScissor (=%" PRIu32 ") is not 0.",
2496*b7893ccfSSadaf Ebrahimi firstScissor);
2497*b7893ccfSSadaf Ebrahimi }
2498*b7893ccfSSadaf Ebrahimi if (scissorCount > 1) {
2499*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2500*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-scissorCount-00594",
2501*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: The multiViewport feature is disabled, but scissorCount (=%" PRIu32 ") is not 1.",
2502*b7893ccfSSadaf Ebrahimi scissorCount);
2503*b7893ccfSSadaf Ebrahimi }
2504*b7893ccfSSadaf Ebrahimi } else { // multiViewport enabled
2505*b7893ccfSSadaf Ebrahimi const uint64_t sum = static_cast<uint64_t>(firstScissor) + static_cast<uint64_t>(scissorCount);
2506*b7893ccfSSadaf Ebrahimi if (sum > device_limits.maxViewports) {
2507*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2508*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-firstScissor-00592",
2509*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: firstScissor + scissorCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
2510*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
2511*b7893ccfSSadaf Ebrahimi firstScissor, scissorCount, sum, device_limits.maxViewports);
2512*b7893ccfSSadaf Ebrahimi }
2513*b7893ccfSSadaf Ebrahimi }
2514*b7893ccfSSadaf Ebrahimi
2515*b7893ccfSSadaf Ebrahimi if (pScissors) {
2516*b7893ccfSSadaf Ebrahimi for (uint32_t scissor_i = 0; scissor_i < scissorCount; ++scissor_i) {
2517*b7893ccfSSadaf Ebrahimi const auto &scissor = pScissors[scissor_i]; // will crash on invalid ptr
2518*b7893ccfSSadaf Ebrahimi
2519*b7893ccfSSadaf Ebrahimi if (scissor.offset.x < 0) {
2520*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2521*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
2522*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.", scissor_i,
2523*b7893ccfSSadaf Ebrahimi scissor.offset.x);
2524*b7893ccfSSadaf Ebrahimi }
2525*b7893ccfSSadaf Ebrahimi
2526*b7893ccfSSadaf Ebrahimi if (scissor.offset.y < 0) {
2527*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2528*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-x-00595",
2529*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.", scissor_i,
2530*b7893ccfSSadaf Ebrahimi scissor.offset.y);
2531*b7893ccfSSadaf Ebrahimi }
2532*b7893ccfSSadaf Ebrahimi
2533*b7893ccfSSadaf Ebrahimi const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
2534*b7893ccfSSadaf Ebrahimi if (x_sum > INT32_MAX) {
2535*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2536*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00596",
2537*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2538*b7893ccfSSadaf Ebrahimi ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2539*b7893ccfSSadaf Ebrahimi scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
2540*b7893ccfSSadaf Ebrahimi }
2541*b7893ccfSSadaf Ebrahimi
2542*b7893ccfSSadaf Ebrahimi const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
2543*b7893ccfSSadaf Ebrahimi if (y_sum > INT32_MAX) {
2544*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2545*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetScissor-offset-00597",
2546*b7893ccfSSadaf Ebrahimi "vkCmdSetScissor: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
2547*b7893ccfSSadaf Ebrahimi ") of pScissors[%" PRIu32 "] will overflow int32_t.",
2548*b7893ccfSSadaf Ebrahimi scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
2549*b7893ccfSSadaf Ebrahimi }
2550*b7893ccfSSadaf Ebrahimi }
2551*b7893ccfSSadaf Ebrahimi }
2552*b7893ccfSSadaf Ebrahimi
2553*b7893ccfSSadaf Ebrahimi return skip;
2554*b7893ccfSSadaf Ebrahimi }
2555*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)2556*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
2557*b7893ccfSSadaf Ebrahimi bool skip = false;
2558*b7893ccfSSadaf Ebrahimi
2559*b7893ccfSSadaf Ebrahimi if (!physical_device_features.wideLines && (lineWidth != 1.0f)) {
2560*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2561*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetLineWidth-lineWidth-00788",
2562*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceFeatures::wideLines is disabled, but lineWidth (=%f) is not 1.0.", lineWidth);
2563*b7893ccfSSadaf Ebrahimi }
2564*b7893ccfSSadaf Ebrahimi
2565*b7893ccfSSadaf Ebrahimi return skip;
2566*b7893ccfSSadaf Ebrahimi }
2567*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer,uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)2568*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount,
2569*b7893ccfSSadaf Ebrahimi uint32_t firstVertex, uint32_t firstInstance) {
2570*b7893ccfSSadaf Ebrahimi bool skip = false;
2571*b7893ccfSSadaf Ebrahimi if (vertexCount == 0) {
2572*b7893ccfSSadaf Ebrahimi // TODO: Verify against Valid Usage section. I don't see a non-zero vertexCount listed, may need to add that and make
2573*b7893ccfSSadaf Ebrahimi // this an error or leave as is.
2574*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2575*b7893ccfSSadaf Ebrahimi kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t vertexCount, is 0");
2576*b7893ccfSSadaf Ebrahimi }
2577*b7893ccfSSadaf Ebrahimi
2578*b7893ccfSSadaf Ebrahimi if (instanceCount == 0) {
2579*b7893ccfSSadaf Ebrahimi // TODO: Verify against Valid Usage section. I don't see a non-zero instanceCount listed, may need to add that and make
2580*b7893ccfSSadaf Ebrahimi // this an error or leave as is.
2581*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2582*b7893ccfSSadaf Ebrahimi kVUID_PVError_RequiredParameter, "vkCmdDraw parameter, uint32_t instanceCount, is 0");
2583*b7893ccfSSadaf Ebrahimi }
2584*b7893ccfSSadaf Ebrahimi return skip;
2585*b7893ccfSSadaf Ebrahimi }
2586*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t count,uint32_t stride)2587*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
2588*b7893ccfSSadaf Ebrahimi uint32_t count, uint32_t stride) {
2589*b7893ccfSSadaf Ebrahimi bool skip = false;
2590*b7893ccfSSadaf Ebrahimi
2591*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
2592*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2593*b7893ccfSSadaf Ebrahimi kVUID_PVError_DeviceFeature,
2594*b7893ccfSSadaf Ebrahimi "CmdDrawIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
2595*b7893ccfSSadaf Ebrahimi }
2596*b7893ccfSSadaf Ebrahimi return skip;
2597*b7893ccfSSadaf Ebrahimi }
2598*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t count,uint32_t stride)2599*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2600*b7893ccfSSadaf Ebrahimi VkDeviceSize offset, uint32_t count, uint32_t stride) {
2601*b7893ccfSSadaf Ebrahimi bool skip = false;
2602*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiDrawIndirect && ((count > 1))) {
2603*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2604*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, kVUID_PVError_DeviceFeature,
2605*b7893ccfSSadaf Ebrahimi "CmdDrawIndexedIndirect(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d", count);
2606*b7893ccfSSadaf Ebrahimi }
2607*b7893ccfSSadaf Ebrahimi return skip;
2608*b7893ccfSSadaf Ebrahimi }
2609*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdClearAttachments(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkClearAttachment * pAttachments,uint32_t rectCount,const VkClearRect * pRects)2610*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
2611*b7893ccfSSadaf Ebrahimi const VkClearAttachment *pAttachments, uint32_t rectCount,
2612*b7893ccfSSadaf Ebrahimi const VkClearRect *pRects) {
2613*b7893ccfSSadaf Ebrahimi bool skip = false;
2614*b7893ccfSSadaf Ebrahimi for (uint32_t rect = 0; rect < rectCount; rect++) {
2615*b7893ccfSSadaf Ebrahimi if (pRects[rect].layerCount == 0) {
2616*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2617*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdClearAttachments-layerCount-01934",
2618*b7893ccfSSadaf Ebrahimi "CmdClearAttachments(): pRects[%d].layerCount is zero.", rect);
2619*b7893ccfSSadaf Ebrahimi }
2620*b7893ccfSSadaf Ebrahimi }
2621*b7893ccfSSadaf Ebrahimi return skip;
2622*b7893ccfSSadaf Ebrahimi }
2623*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * pRegions)2624*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2625*b7893ccfSSadaf Ebrahimi VkImageLayout srcImageLayout, VkImage dstImage,
2626*b7893ccfSSadaf Ebrahimi VkImageLayout dstImageLayout, uint32_t regionCount,
2627*b7893ccfSSadaf Ebrahimi const VkImageCopy *pRegions) {
2628*b7893ccfSSadaf Ebrahimi bool skip = false;
2629*b7893ccfSSadaf Ebrahimi
2630*b7893ccfSSadaf Ebrahimi VkImageAspectFlags legal_aspect_flags =
2631*b7893ccfSSadaf Ebrahimi VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
2632*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
2633*b7893ccfSSadaf Ebrahimi legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2634*b7893ccfSSadaf Ebrahimi }
2635*b7893ccfSSadaf Ebrahimi
2636*b7893ccfSSadaf Ebrahimi if (pRegions != nullptr) {
2637*b7893ccfSSadaf Ebrahimi if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
2638*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2639*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2640*b7893ccfSSadaf Ebrahimi "VUID-VkImageSubresourceLayers-aspectMask-parameter",
2641*b7893ccfSSadaf Ebrahimi "vkCmdCopyImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator.");
2642*b7893ccfSSadaf Ebrahimi }
2643*b7893ccfSSadaf Ebrahimi if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
2644*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2645*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2646*b7893ccfSSadaf Ebrahimi "VUID-VkImageSubresourceLayers-aspectMask-parameter",
2647*b7893ccfSSadaf Ebrahimi "vkCmdCopyImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator.");
2648*b7893ccfSSadaf Ebrahimi }
2649*b7893ccfSSadaf Ebrahimi }
2650*b7893ccfSSadaf Ebrahimi return skip;
2651*b7893ccfSSadaf Ebrahimi }
2652*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * pRegions,VkFilter filter)2653*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdBlitImage(VkCommandBuffer commandBuffer, VkImage srcImage,
2654*b7893ccfSSadaf Ebrahimi VkImageLayout srcImageLayout, VkImage dstImage,
2655*b7893ccfSSadaf Ebrahimi VkImageLayout dstImageLayout, uint32_t regionCount,
2656*b7893ccfSSadaf Ebrahimi const VkImageBlit *pRegions, VkFilter filter) {
2657*b7893ccfSSadaf Ebrahimi bool skip = false;
2658*b7893ccfSSadaf Ebrahimi
2659*b7893ccfSSadaf Ebrahimi VkImageAspectFlags legal_aspect_flags =
2660*b7893ccfSSadaf Ebrahimi VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
2661*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
2662*b7893ccfSSadaf Ebrahimi legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2663*b7893ccfSSadaf Ebrahimi }
2664*b7893ccfSSadaf Ebrahimi
2665*b7893ccfSSadaf Ebrahimi if (pRegions != nullptr) {
2666*b7893ccfSSadaf Ebrahimi if ((pRegions->srcSubresource.aspectMask & legal_aspect_flags) == 0) {
2667*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2668*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2669*b7893ccfSSadaf Ebrahimi kVUID_PVError_UnrecognizedValue,
2670*b7893ccfSSadaf Ebrahimi "vkCmdBlitImage() parameter, VkImageAspect pRegions->srcSubresource.aspectMask, is an unrecognized enumerator");
2671*b7893ccfSSadaf Ebrahimi }
2672*b7893ccfSSadaf Ebrahimi if ((pRegions->dstSubresource.aspectMask & legal_aspect_flags) == 0) {
2673*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2674*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2675*b7893ccfSSadaf Ebrahimi kVUID_PVError_UnrecognizedValue,
2676*b7893ccfSSadaf Ebrahimi "vkCmdBlitImage() parameter, VkImageAspect pRegions->dstSubresource.aspectMask, is an unrecognized enumerator");
2677*b7893ccfSSadaf Ebrahimi }
2678*b7893ccfSSadaf Ebrahimi }
2679*b7893ccfSSadaf Ebrahimi return skip;
2680*b7893ccfSSadaf Ebrahimi }
2681*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer,VkBuffer srcBuffer,VkImage dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * pRegions)2682*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
2683*b7893ccfSSadaf Ebrahimi VkImage dstImage, VkImageLayout dstImageLayout,
2684*b7893ccfSSadaf Ebrahimi uint32_t regionCount, const VkBufferImageCopy *pRegions) {
2685*b7893ccfSSadaf Ebrahimi bool skip = false;
2686*b7893ccfSSadaf Ebrahimi
2687*b7893ccfSSadaf Ebrahimi VkImageAspectFlags legal_aspect_flags =
2688*b7893ccfSSadaf Ebrahimi VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
2689*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
2690*b7893ccfSSadaf Ebrahimi legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2691*b7893ccfSSadaf Ebrahimi }
2692*b7893ccfSSadaf Ebrahimi
2693*b7893ccfSSadaf Ebrahimi if (pRegions != nullptr) {
2694*b7893ccfSSadaf Ebrahimi if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
2695*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2696*b7893ccfSSadaf Ebrahimi kVUID_PVError_UnrecognizedValue,
2697*b7893ccfSSadaf Ebrahimi "vkCmdCopyBufferToImage() parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an "
2698*b7893ccfSSadaf Ebrahimi "unrecognized enumerator");
2699*b7893ccfSSadaf Ebrahimi }
2700*b7893ccfSSadaf Ebrahimi }
2701*b7893ccfSSadaf Ebrahimi return skip;
2702*b7893ccfSSadaf Ebrahimi }
2703*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer,VkImage srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * pRegions)2704*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
2705*b7893ccfSSadaf Ebrahimi VkImageLayout srcImageLayout, VkBuffer dstBuffer,
2706*b7893ccfSSadaf Ebrahimi uint32_t regionCount, const VkBufferImageCopy *pRegions) {
2707*b7893ccfSSadaf Ebrahimi bool skip = false;
2708*b7893ccfSSadaf Ebrahimi
2709*b7893ccfSSadaf Ebrahimi VkImageAspectFlags legal_aspect_flags =
2710*b7893ccfSSadaf Ebrahimi VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_METADATA_BIT;
2711*b7893ccfSSadaf Ebrahimi if (device_extensions.vk_khr_sampler_ycbcr_conversion) {
2712*b7893ccfSSadaf Ebrahimi legal_aspect_flags |= (VK_IMAGE_ASPECT_PLANE_0_BIT_KHR | VK_IMAGE_ASPECT_PLANE_1_BIT_KHR | VK_IMAGE_ASPECT_PLANE_2_BIT_KHR);
2713*b7893ccfSSadaf Ebrahimi }
2714*b7893ccfSSadaf Ebrahimi
2715*b7893ccfSSadaf Ebrahimi if (pRegions != nullptr) {
2716*b7893ccfSSadaf Ebrahimi if ((pRegions->imageSubresource.aspectMask & legal_aspect_flags) == 0) {
2717*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2718*b7893ccfSSadaf Ebrahimi kVUID_PVError_UnrecognizedValue,
2719*b7893ccfSSadaf Ebrahimi "vkCmdCopyImageToBuffer parameter, VkImageAspect pRegions->imageSubresource.aspectMask, is an unrecognized "
2720*b7893ccfSSadaf Ebrahimi "enumerator");
2721*b7893ccfSSadaf Ebrahimi }
2722*b7893ccfSSadaf Ebrahimi }
2723*b7893ccfSSadaf Ebrahimi return skip;
2724*b7893ccfSSadaf Ebrahimi }
2725*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize dataSize,const void * pData)2726*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2727*b7893ccfSSadaf Ebrahimi VkDeviceSize dstOffset, VkDeviceSize dataSize, const void *pData) {
2728*b7893ccfSSadaf Ebrahimi bool skip = false;
2729*b7893ccfSSadaf Ebrahimi
2730*b7893ccfSSadaf Ebrahimi if (dstOffset & 3) {
2731*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2732*b7893ccfSSadaf Ebrahimi "VUID-vkCmdUpdateBuffer-dstOffset-00036",
2733*b7893ccfSSadaf Ebrahimi "vkCmdUpdateBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.",
2734*b7893ccfSSadaf Ebrahimi dstOffset);
2735*b7893ccfSSadaf Ebrahimi }
2736*b7893ccfSSadaf Ebrahimi
2737*b7893ccfSSadaf Ebrahimi if ((dataSize <= 0) || (dataSize > 65536)) {
2738*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2739*b7893ccfSSadaf Ebrahimi "VUID-vkCmdUpdateBuffer-dataSize-00037",
2740*b7893ccfSSadaf Ebrahimi "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64
2741*b7893ccfSSadaf Ebrahimi "), must be greater than zero and less than or equal to 65536.",
2742*b7893ccfSSadaf Ebrahimi dataSize);
2743*b7893ccfSSadaf Ebrahimi } else if (dataSize & 3) {
2744*b7893ccfSSadaf Ebrahimi skip |=
2745*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2746*b7893ccfSSadaf Ebrahimi "VUID-vkCmdUpdateBuffer-dataSize-00038",
2747*b7893ccfSSadaf Ebrahimi "vkCmdUpdateBuffer() parameter, VkDeviceSize dataSize (0x%" PRIxLEAST64 "), is not a multiple of 4.", dataSize);
2748*b7893ccfSSadaf Ebrahimi }
2749*b7893ccfSSadaf Ebrahimi return skip;
2750*b7893ccfSSadaf Ebrahimi }
2751*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer,VkBuffer dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)2752*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdFillBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
2753*b7893ccfSSadaf Ebrahimi VkDeviceSize dstOffset, VkDeviceSize size, uint32_t data) {
2754*b7893ccfSSadaf Ebrahimi bool skip = false;
2755*b7893ccfSSadaf Ebrahimi
2756*b7893ccfSSadaf Ebrahimi if (dstOffset & 3) {
2757*b7893ccfSSadaf Ebrahimi skip |=
2758*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2759*b7893ccfSSadaf Ebrahimi "VUID-vkCmdFillBuffer-dstOffset-00025",
2760*b7893ccfSSadaf Ebrahimi "vkCmdFillBuffer() parameter, VkDeviceSize dstOffset (0x%" PRIxLEAST64 "), is not a multiple of 4.", dstOffset);
2761*b7893ccfSSadaf Ebrahimi }
2762*b7893ccfSSadaf Ebrahimi
2763*b7893ccfSSadaf Ebrahimi if (size != VK_WHOLE_SIZE) {
2764*b7893ccfSSadaf Ebrahimi if (size <= 0) {
2765*b7893ccfSSadaf Ebrahimi skip |=
2766*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2767*b7893ccfSSadaf Ebrahimi "VUID-vkCmdFillBuffer-size-00026",
2768*b7893ccfSSadaf Ebrahimi "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), must be greater than zero.", size);
2769*b7893ccfSSadaf Ebrahimi } else if (size & 3) {
2770*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2771*b7893ccfSSadaf Ebrahimi "VUID-vkCmdFillBuffer-size-00028",
2772*b7893ccfSSadaf Ebrahimi "vkCmdFillBuffer() parameter, VkDeviceSize size (0x%" PRIxLEAST64 "), is not a multiple of 4.", size);
2773*b7893ccfSSadaf Ebrahimi }
2774*b7893ccfSSadaf Ebrahimi }
2775*b7893ccfSSadaf Ebrahimi return skip;
2776*b7893ccfSSadaf Ebrahimi }
2777*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSwapchainKHR * pSwapchain)2778*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
2779*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2780*b7893ccfSSadaf Ebrahimi VkSwapchainKHR *pSwapchain) {
2781*b7893ccfSSadaf Ebrahimi bool skip = false;
2782*b7893ccfSSadaf Ebrahimi
2783*b7893ccfSSadaf Ebrahimi const LogMiscParams log_misc{VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, VK_NULL_HANDLE, "vkCreateSwapchainKHR"};
2784*b7893ccfSSadaf Ebrahimi
2785*b7893ccfSSadaf Ebrahimi if (pCreateInfo != nullptr) {
2786*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
2787*b7893ccfSSadaf Ebrahimi if (pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
2788*b7893ccfSSadaf Ebrahimi // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
2789*b7893ccfSSadaf Ebrahimi if (pCreateInfo->queueFamilyIndexCount <= 1) {
2790*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2791*b7893ccfSSadaf Ebrahimi "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278",
2792*b7893ccfSSadaf Ebrahimi "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
2793*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount must be greater than 1.");
2794*b7893ccfSSadaf Ebrahimi }
2795*b7893ccfSSadaf Ebrahimi
2796*b7893ccfSSadaf Ebrahimi // If imageSharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
2797*b7893ccfSSadaf Ebrahimi // queueFamilyIndexCount uint32_t values
2798*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pQueueFamilyIndices == nullptr) {
2799*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2800*b7893ccfSSadaf Ebrahimi "VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01277",
2801*b7893ccfSSadaf Ebrahimi "vkCreateSwapchainKHR(): if pCreateInfo->imageSharingMode is VK_SHARING_MODE_CONCURRENT, "
2802*b7893ccfSSadaf Ebrahimi "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
2803*b7893ccfSSadaf Ebrahimi "pCreateInfo->queueFamilyIndexCount uint32_t values.");
2804*b7893ccfSSadaf Ebrahimi }
2805*b7893ccfSSadaf Ebrahimi }
2806*b7893ccfSSadaf Ebrahimi
2807*b7893ccfSSadaf Ebrahimi skip |= ValidateGreaterThanZero(pCreateInfo->imageArrayLayers, "pCreateInfo->imageArrayLayers",
2808*b7893ccfSSadaf Ebrahimi "VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275", log_misc);
2809*b7893ccfSSadaf Ebrahimi }
2810*b7893ccfSSadaf Ebrahimi
2811*b7893ccfSSadaf Ebrahimi return skip;
2812*b7893ccfSSadaf Ebrahimi }
2813*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateQueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * pPresentInfo)2814*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPresentInfo) {
2815*b7893ccfSSadaf Ebrahimi bool skip = false;
2816*b7893ccfSSadaf Ebrahimi
2817*b7893ccfSSadaf Ebrahimi if (pPresentInfo && pPresentInfo->pNext) {
2818*b7893ccfSSadaf Ebrahimi const auto *present_regions = lvl_find_in_chain<VkPresentRegionsKHR>(pPresentInfo->pNext);
2819*b7893ccfSSadaf Ebrahimi if (present_regions) {
2820*b7893ccfSSadaf Ebrahimi // TODO: This and all other pNext extension dependencies should be added to code-generation
2821*b7893ccfSSadaf Ebrahimi skip |= require_device_extension(device_extensions.vk_khr_incremental_present, "vkQueuePresentKHR",
2822*b7893ccfSSadaf Ebrahimi VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
2823*b7893ccfSSadaf Ebrahimi if (present_regions->swapchainCount != pPresentInfo->swapchainCount) {
2824*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2825*b7893ccfSSadaf Ebrahimi kVUID_PVError_InvalidUsage,
2826*b7893ccfSSadaf Ebrahimi "QueuePresentKHR(): pPresentInfo->swapchainCount has a value of %i but VkPresentRegionsKHR "
2827*b7893ccfSSadaf Ebrahimi "extension swapchainCount is %i. These values must be equal.",
2828*b7893ccfSSadaf Ebrahimi pPresentInfo->swapchainCount, present_regions->swapchainCount);
2829*b7893ccfSSadaf Ebrahimi }
2830*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext("QueuePresentKHR", "pCreateInfo->pNext->pNext", NULL, present_regions->pNext, 0, NULL,
2831*b7893ccfSSadaf Ebrahimi GeneratedVulkanHeaderVersion, "VUID-VkPresentInfoKHR-pNext-pNext");
2832*b7893ccfSSadaf Ebrahimi skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->swapchainCount", "pCreateInfo->pNext->pRegions",
2833*b7893ccfSSadaf Ebrahimi present_regions->swapchainCount, &present_regions->pRegions, true, false, kVUIDUndefined,
2834*b7893ccfSSadaf Ebrahimi kVUIDUndefined);
2835*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < present_regions->swapchainCount; ++i) {
2836*b7893ccfSSadaf Ebrahimi skip |= validate_array("QueuePresentKHR", "pCreateInfo->pNext->pRegions[].rectangleCount",
2837*b7893ccfSSadaf Ebrahimi "pCreateInfo->pNext->pRegions[].pRectangles", present_regions->pRegions[i].rectangleCount,
2838*b7893ccfSSadaf Ebrahimi &present_regions->pRegions[i].pRectangles, true, false, kVUIDUndefined, kVUIDUndefined);
2839*b7893ccfSSadaf Ebrahimi }
2840*b7893ccfSSadaf Ebrahimi }
2841*b7893ccfSSadaf Ebrahimi }
2842*b7893ccfSSadaf Ebrahimi
2843*b7893ccfSSadaf Ebrahimi return skip;
2844*b7893ccfSSadaf Ebrahimi }
2845*b7893ccfSSadaf Ebrahimi
2846*b7893ccfSSadaf Ebrahimi #ifdef VK_USE_PLATFORM_WIN32_KHR
manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance,const VkWin32SurfaceCreateInfoKHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkSurfaceKHR * pSurface)2847*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateWin32SurfaceKHR(VkInstance instance,
2848*b7893ccfSSadaf Ebrahimi const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
2849*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2850*b7893ccfSSadaf Ebrahimi VkSurfaceKHR *pSurface) {
2851*b7893ccfSSadaf Ebrahimi bool skip = false;
2852*b7893ccfSSadaf Ebrahimi
2853*b7893ccfSSadaf Ebrahimi if (pCreateInfo->hwnd == nullptr) {
2854*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
2855*b7893ccfSSadaf Ebrahimi "VUID-VkWin32SurfaceCreateInfoKHR-hwnd-01308",
2856*b7893ccfSSadaf Ebrahimi "vkCreateWin32SurfaceKHR(): hwnd must be a valid Win32 HWND but hwnd is NULL.");
2857*b7893ccfSSadaf Ebrahimi }
2858*b7893ccfSSadaf Ebrahimi
2859*b7893ccfSSadaf Ebrahimi return skip;
2860*b7893ccfSSadaf Ebrahimi }
2861*b7893ccfSSadaf Ebrahimi #endif // VK_USE_PLATFORM_WIN32_KHR
2862*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateDescriptorPool(VkDevice device,const VkDescriptorPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDescriptorPool * pDescriptorPool)2863*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo,
2864*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
2865*b7893ccfSSadaf Ebrahimi VkDescriptorPool *pDescriptorPool) {
2866*b7893ccfSSadaf Ebrahimi bool skip = false;
2867*b7893ccfSSadaf Ebrahimi
2868*b7893ccfSSadaf Ebrahimi if (pCreateInfo) {
2869*b7893ccfSSadaf Ebrahimi if (pCreateInfo->maxSets <= 0) {
2870*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
2871*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkDescriptorPoolCreateInfo-maxSets-00301",
2872*b7893ccfSSadaf Ebrahimi "vkCreateDescriptorPool(): pCreateInfo->maxSets is not greater than 0.");
2873*b7893ccfSSadaf Ebrahimi }
2874*b7893ccfSSadaf Ebrahimi
2875*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pPoolSizes) {
2876*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < pCreateInfo->poolSizeCount; ++i) {
2877*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pPoolSizes[i].descriptorCount <= 0) {
2878*b7893ccfSSadaf Ebrahimi skip |= log_msg(
2879*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, VK_NULL_HANDLE,
2880*b7893ccfSSadaf Ebrahimi "VUID-VkDescriptorPoolSize-descriptorCount-00302",
2881*b7893ccfSSadaf Ebrahimi "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not greater than 0.", i);
2882*b7893ccfSSadaf Ebrahimi }
2883*b7893ccfSSadaf Ebrahimi if (pCreateInfo->pPoolSizes[i].type == VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT &&
2884*b7893ccfSSadaf Ebrahimi (pCreateInfo->pPoolSizes[i].descriptorCount % 4) != 0) {
2885*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
2886*b7893ccfSSadaf Ebrahimi VK_NULL_HANDLE, "VUID-VkDescriptorPoolSize-type-02218",
2887*b7893ccfSSadaf Ebrahimi "vkCreateDescriptorPool(): pCreateInfo->pPoolSizes[%" PRIu32
2888*b7893ccfSSadaf Ebrahimi "].type is VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT "
2889*b7893ccfSSadaf Ebrahimi " and pCreateInfo->pPoolSizes[%" PRIu32 "].descriptorCount is not a multiple of 4.",
2890*b7893ccfSSadaf Ebrahimi i, i);
2891*b7893ccfSSadaf Ebrahimi }
2892*b7893ccfSSadaf Ebrahimi }
2893*b7893ccfSSadaf Ebrahimi }
2894*b7893ccfSSadaf Ebrahimi }
2895*b7893ccfSSadaf Ebrahimi
2896*b7893ccfSSadaf Ebrahimi return skip;
2897*b7893ccfSSadaf Ebrahimi }
2898*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer,uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)2899*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDispatch(VkCommandBuffer commandBuffer, uint32_t groupCountX,
2900*b7893ccfSSadaf Ebrahimi uint32_t groupCountY, uint32_t groupCountZ) {
2901*b7893ccfSSadaf Ebrahimi bool skip = false;
2902*b7893ccfSSadaf Ebrahimi
2903*b7893ccfSSadaf Ebrahimi if (groupCountX > device_limits.maxComputeWorkGroupCount[0]) {
2904*b7893ccfSSadaf Ebrahimi skip |=
2905*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2906*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountX-00386",
2907*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): groupCountX (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2908*b7893ccfSSadaf Ebrahimi groupCountX, device_limits.maxComputeWorkGroupCount[0]);
2909*b7893ccfSSadaf Ebrahimi }
2910*b7893ccfSSadaf Ebrahimi
2911*b7893ccfSSadaf Ebrahimi if (groupCountY > device_limits.maxComputeWorkGroupCount[1]) {
2912*b7893ccfSSadaf Ebrahimi skip |=
2913*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2914*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountY-00387",
2915*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): groupCountY (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2916*b7893ccfSSadaf Ebrahimi groupCountY, device_limits.maxComputeWorkGroupCount[1]);
2917*b7893ccfSSadaf Ebrahimi }
2918*b7893ccfSSadaf Ebrahimi
2919*b7893ccfSSadaf Ebrahimi if (groupCountZ > device_limits.maxComputeWorkGroupCount[2]) {
2920*b7893ccfSSadaf Ebrahimi skip |=
2921*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2922*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatch-groupCountZ-00388",
2923*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): groupCountZ (%" PRIu32 ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2924*b7893ccfSSadaf Ebrahimi groupCountZ, device_limits.maxComputeWorkGroupCount[2]);
2925*b7893ccfSSadaf Ebrahimi }
2926*b7893ccfSSadaf Ebrahimi
2927*b7893ccfSSadaf Ebrahimi return skip;
2928*b7893ccfSSadaf Ebrahimi }
2929*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset)2930*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer buffer,
2931*b7893ccfSSadaf Ebrahimi VkDeviceSize offset) {
2932*b7893ccfSSadaf Ebrahimi bool skip = false;
2933*b7893ccfSSadaf Ebrahimi
2934*b7893ccfSSadaf Ebrahimi if ((offset % 4) != 0) {
2935*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2936*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchIndirect-offset-02710",
2937*b7893ccfSSadaf Ebrahimi "vkCmdDispatchIndirect(): offset (%" PRIu64 ") must be a multiple of 4.", offset);
2938*b7893ccfSSadaf Ebrahimi }
2939*b7893ccfSSadaf Ebrahimi return skip;
2940*b7893ccfSSadaf Ebrahimi }
2941*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer,uint32_t baseGroupX,uint32_t baseGroupY,uint32_t baseGroupZ,uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)2942*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDispatchBaseKHR(VkCommandBuffer commandBuffer, uint32_t baseGroupX,
2943*b7893ccfSSadaf Ebrahimi uint32_t baseGroupY, uint32_t baseGroupZ, uint32_t groupCountX,
2944*b7893ccfSSadaf Ebrahimi uint32_t groupCountY, uint32_t groupCountZ) {
2945*b7893ccfSSadaf Ebrahimi bool skip = false;
2946*b7893ccfSSadaf Ebrahimi
2947*b7893ccfSSadaf Ebrahimi // Paired if {} else if {} tests used to avoid any possible uint underflow
2948*b7893ccfSSadaf Ebrahimi uint32_t limit = device_limits.maxComputeWorkGroupCount[0];
2949*b7893ccfSSadaf Ebrahimi if (baseGroupX >= limit) {
2950*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2951*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00421",
2952*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): baseGroupX (%" PRIu32
2953*b7893ccfSSadaf Ebrahimi ") equals or exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2954*b7893ccfSSadaf Ebrahimi baseGroupX, limit);
2955*b7893ccfSSadaf Ebrahimi } else if (groupCountX > (limit - baseGroupX)) {
2956*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2957*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountX-00424",
2958*b7893ccfSSadaf Ebrahimi "vkCmdDispatchBaseKHR(): baseGroupX (%" PRIu32 ") + groupCountX (%" PRIu32
2959*b7893ccfSSadaf Ebrahimi ") exceeds device limit maxComputeWorkGroupCount[0] (%" PRIu32 ").",
2960*b7893ccfSSadaf Ebrahimi baseGroupX, groupCountX, limit);
2961*b7893ccfSSadaf Ebrahimi }
2962*b7893ccfSSadaf Ebrahimi
2963*b7893ccfSSadaf Ebrahimi limit = device_limits.maxComputeWorkGroupCount[1];
2964*b7893ccfSSadaf Ebrahimi if (baseGroupY >= limit) {
2965*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2966*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupX-00422",
2967*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): baseGroupY (%" PRIu32
2968*b7893ccfSSadaf Ebrahimi ") equals or exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2969*b7893ccfSSadaf Ebrahimi baseGroupY, limit);
2970*b7893ccfSSadaf Ebrahimi } else if (groupCountY > (limit - baseGroupY)) {
2971*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2972*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountY-00425",
2973*b7893ccfSSadaf Ebrahimi "vkCmdDispatchBaseKHR(): baseGroupY (%" PRIu32 ") + groupCountY (%" PRIu32
2974*b7893ccfSSadaf Ebrahimi ") exceeds device limit maxComputeWorkGroupCount[1] (%" PRIu32 ").",
2975*b7893ccfSSadaf Ebrahimi baseGroupY, groupCountY, limit);
2976*b7893ccfSSadaf Ebrahimi }
2977*b7893ccfSSadaf Ebrahimi
2978*b7893ccfSSadaf Ebrahimi limit = device_limits.maxComputeWorkGroupCount[2];
2979*b7893ccfSSadaf Ebrahimi if (baseGroupZ >= limit) {
2980*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2981*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-baseGroupZ-00423",
2982*b7893ccfSSadaf Ebrahimi "vkCmdDispatch(): baseGroupZ (%" PRIu32
2983*b7893ccfSSadaf Ebrahimi ") equals or exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2984*b7893ccfSSadaf Ebrahimi baseGroupZ, limit);
2985*b7893ccfSSadaf Ebrahimi } else if (groupCountZ > (limit - baseGroupZ)) {
2986*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
2987*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDispatchBase-groupCountZ-00426",
2988*b7893ccfSSadaf Ebrahimi "vkCmdDispatchBaseKHR(): baseGroupZ (%" PRIu32 ") + groupCountZ (%" PRIu32
2989*b7893ccfSSadaf Ebrahimi ") exceeds device limit maxComputeWorkGroupCount[2] (%" PRIu32 ").",
2990*b7893ccfSSadaf Ebrahimi baseGroupZ, groupCountZ, limit);
2991*b7893ccfSSadaf Ebrahimi }
2992*b7893ccfSSadaf Ebrahimi
2993*b7893ccfSSadaf Ebrahimi return skip;
2994*b7893ccfSSadaf Ebrahimi }
2995*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer,uint32_t firstExclusiveScissor,uint32_t exclusiveScissorCount,const VkRect2D * pExclusiveScissors)2996*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetExclusiveScissorNV(VkCommandBuffer commandBuffer,
2997*b7893ccfSSadaf Ebrahimi uint32_t firstExclusiveScissor,
2998*b7893ccfSSadaf Ebrahimi uint32_t exclusiveScissorCount,
2999*b7893ccfSSadaf Ebrahimi const VkRect2D *pExclusiveScissors) {
3000*b7893ccfSSadaf Ebrahimi bool skip = false;
3001*b7893ccfSSadaf Ebrahimi
3002*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiViewport) {
3003*b7893ccfSSadaf Ebrahimi if (firstExclusiveScissor != 0) {
3004*b7893ccfSSadaf Ebrahimi skip |=
3005*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3006*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02035",
3007*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but firstExclusiveScissor (=%" PRIu32
3008*b7893ccfSSadaf Ebrahimi ") is not 0.",
3009*b7893ccfSSadaf Ebrahimi firstExclusiveScissor);
3010*b7893ccfSSadaf Ebrahimi }
3011*b7893ccfSSadaf Ebrahimi if (exclusiveScissorCount > 1) {
3012*b7893ccfSSadaf Ebrahimi skip |=
3013*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3014*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-exclusiveScissorCount-02036",
3015*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: The multiViewport feature is disabled, but exclusiveScissorCount (=%" PRIu32
3016*b7893ccfSSadaf Ebrahimi ") is not 1.",
3017*b7893ccfSSadaf Ebrahimi exclusiveScissorCount);
3018*b7893ccfSSadaf Ebrahimi }
3019*b7893ccfSSadaf Ebrahimi } else { // multiViewport enabled
3020*b7893ccfSSadaf Ebrahimi const uint64_t sum = static_cast<uint64_t>(firstExclusiveScissor) + static_cast<uint64_t>(exclusiveScissorCount);
3021*b7893ccfSSadaf Ebrahimi if (sum > device_limits.maxViewports) {
3022*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3023*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02034",
3024*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: firstExclusiveScissor + exclusiveScissorCount (=%" PRIu32 " + %" PRIu32
3025*b7893ccfSSadaf Ebrahimi " = %" PRIu64 ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
3026*b7893ccfSSadaf Ebrahimi firstExclusiveScissor, exclusiveScissorCount, sum, device_limits.maxViewports);
3027*b7893ccfSSadaf Ebrahimi }
3028*b7893ccfSSadaf Ebrahimi }
3029*b7893ccfSSadaf Ebrahimi
3030*b7893ccfSSadaf Ebrahimi if (firstExclusiveScissor >= device_limits.maxViewports) {
3031*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3032*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-firstExclusiveScissor-02033",
3033*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: firstExclusiveScissor (=%" PRIu32 ") must be less than maxViewports (=%" PRIu32
3034*b7893ccfSSadaf Ebrahimi ").",
3035*b7893ccfSSadaf Ebrahimi firstExclusiveScissor, device_limits.maxViewports);
3036*b7893ccfSSadaf Ebrahimi }
3037*b7893ccfSSadaf Ebrahimi
3038*b7893ccfSSadaf Ebrahimi if (pExclusiveScissors) {
3039*b7893ccfSSadaf Ebrahimi for (uint32_t scissor_i = 0; scissor_i < exclusiveScissorCount; ++scissor_i) {
3040*b7893ccfSSadaf Ebrahimi const auto &scissor = pExclusiveScissors[scissor_i]; // will crash on invalid ptr
3041*b7893ccfSSadaf Ebrahimi
3042*b7893ccfSSadaf Ebrahimi if (scissor.offset.x < 0) {
3043*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3044*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
3045*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.x (=%" PRIi32 ") is negative.",
3046*b7893ccfSSadaf Ebrahimi scissor_i, scissor.offset.x);
3047*b7893ccfSSadaf Ebrahimi }
3048*b7893ccfSSadaf Ebrahimi
3049*b7893ccfSSadaf Ebrahimi if (scissor.offset.y < 0) {
3050*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3051*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-x-02037",
3052*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: pScissors[%" PRIu32 "].offset.y (=%" PRIi32 ") is negative.",
3053*b7893ccfSSadaf Ebrahimi scissor_i, scissor.offset.y);
3054*b7893ccfSSadaf Ebrahimi }
3055*b7893ccfSSadaf Ebrahimi
3056*b7893ccfSSadaf Ebrahimi const int64_t x_sum = static_cast<int64_t>(scissor.offset.x) + static_cast<int64_t>(scissor.extent.width);
3057*b7893ccfSSadaf Ebrahimi if (x_sum > INT32_MAX) {
3058*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3059*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02038",
3060*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: offset.x + extent.width (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
3061*b7893ccfSSadaf Ebrahimi ") of pScissors[%" PRIu32 "] will overflow int32_t.",
3062*b7893ccfSSadaf Ebrahimi scissor.offset.x, scissor.extent.width, x_sum, scissor_i);
3063*b7893ccfSSadaf Ebrahimi }
3064*b7893ccfSSadaf Ebrahimi
3065*b7893ccfSSadaf Ebrahimi const int64_t y_sum = static_cast<int64_t>(scissor.offset.y) + static_cast<int64_t>(scissor.extent.height);
3066*b7893ccfSSadaf Ebrahimi if (y_sum > INT32_MAX) {
3067*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3068*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetExclusiveScissorNV-offset-02039",
3069*b7893ccfSSadaf Ebrahimi "vkCmdSetExclusiveScissorNV: offset.y + extent.height (=%" PRIi32 " + %" PRIu32 " = %" PRIi64
3070*b7893ccfSSadaf Ebrahimi ") of pScissors[%" PRIu32 "] will overflow int32_t.",
3071*b7893ccfSSadaf Ebrahimi scissor.offset.y, scissor.extent.height, y_sum, scissor_i);
3072*b7893ccfSSadaf Ebrahimi }
3073*b7893ccfSSadaf Ebrahimi }
3074*b7893ccfSSadaf Ebrahimi }
3075*b7893ccfSSadaf Ebrahimi
3076*b7893ccfSSadaf Ebrahimi return skip;
3077*b7893ccfSSadaf Ebrahimi }
3078*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkShadingRatePaletteNV * pShadingRatePalettes)3079*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetViewportShadingRatePaletteNV(
3080*b7893ccfSSadaf Ebrahimi VkCommandBuffer commandBuffer, uint32_t firstViewport, uint32_t viewportCount,
3081*b7893ccfSSadaf Ebrahimi const VkShadingRatePaletteNV *pShadingRatePalettes) {
3082*b7893ccfSSadaf Ebrahimi bool skip = false;
3083*b7893ccfSSadaf Ebrahimi
3084*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiViewport) {
3085*b7893ccfSSadaf Ebrahimi if (firstViewport != 0) {
3086*b7893ccfSSadaf Ebrahimi skip |=
3087*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3088*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02068",
3089*b7893ccfSSadaf Ebrahimi "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but firstViewport (=%" PRIu32
3090*b7893ccfSSadaf Ebrahimi ") is not 0.",
3091*b7893ccfSSadaf Ebrahimi firstViewport);
3092*b7893ccfSSadaf Ebrahimi }
3093*b7893ccfSSadaf Ebrahimi if (viewportCount > 1) {
3094*b7893ccfSSadaf Ebrahimi skip |=
3095*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3096*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-viewportCount-02069",
3097*b7893ccfSSadaf Ebrahimi "vkCmdSetViewportShadingRatePaletteNV: The multiViewport feature is disabled, but viewportCount (=%" PRIu32
3098*b7893ccfSSadaf Ebrahimi ") is not 1.",
3099*b7893ccfSSadaf Ebrahimi viewportCount);
3100*b7893ccfSSadaf Ebrahimi }
3101*b7893ccfSSadaf Ebrahimi }
3102*b7893ccfSSadaf Ebrahimi
3103*b7893ccfSSadaf Ebrahimi if (firstViewport >= device_limits.maxViewports) {
3104*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3105*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02066",
3106*b7893ccfSSadaf Ebrahimi "vkCmdSetViewportShadingRatePaletteNV: firstViewport (=%" PRIu32
3107*b7893ccfSSadaf Ebrahimi ") must be less than maxViewports (=%" PRIu32 ").",
3108*b7893ccfSSadaf Ebrahimi firstViewport, device_limits.maxViewports);
3109*b7893ccfSSadaf Ebrahimi }
3110*b7893ccfSSadaf Ebrahimi
3111*b7893ccfSSadaf Ebrahimi const uint64_t sum = static_cast<uint64_t>(firstViewport) + static_cast<uint64_t>(viewportCount);
3112*b7893ccfSSadaf Ebrahimi if (sum > device_limits.maxViewports) {
3113*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3114*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetViewportShadingRatePaletteNV-firstViewport-02067",
3115*b7893ccfSSadaf Ebrahimi "vkCmdSetViewportShadingRatePaletteNV: firstViewport + viewportCount (=%" PRIu32 " + %" PRIu32 " = %" PRIu64
3116*b7893ccfSSadaf Ebrahimi ") is greater than VkPhysicalDeviceLimits::maxViewports (=%" PRIu32 ").",
3117*b7893ccfSSadaf Ebrahimi firstViewport, viewportCount, sum, device_limits.maxViewports);
3118*b7893ccfSSadaf Ebrahimi }
3119*b7893ccfSSadaf Ebrahimi
3120*b7893ccfSSadaf Ebrahimi return skip;
3121*b7893ccfSSadaf Ebrahimi }
3122*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,VkCoarseSampleOrderTypeNV sampleOrderType,uint32_t customSampleOrderCount,const VkCoarseSampleOrderCustomNV * pCustomSampleOrders)3123*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetCoarseSampleOrderNV(VkCommandBuffer commandBuffer,
3124*b7893ccfSSadaf Ebrahimi VkCoarseSampleOrderTypeNV sampleOrderType,
3125*b7893ccfSSadaf Ebrahimi uint32_t customSampleOrderCount,
3126*b7893ccfSSadaf Ebrahimi const VkCoarseSampleOrderCustomNV *pCustomSampleOrders) {
3127*b7893ccfSSadaf Ebrahimi bool skip = false;
3128*b7893ccfSSadaf Ebrahimi
3129*b7893ccfSSadaf Ebrahimi if (sampleOrderType != VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV && customSampleOrderCount != 0) {
3130*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3131*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetCoarseSampleOrderNV-sampleOrderType-02081",
3132*b7893ccfSSadaf Ebrahimi "vkCmdSetCoarseSampleOrderNV: If sampleOrderType is not VK_COARSE_SAMPLE_ORDER_TYPE_CUSTOM_NV, "
3133*b7893ccfSSadaf Ebrahimi "customSampleOrderCount must be 0.");
3134*b7893ccfSSadaf Ebrahimi }
3135*b7893ccfSSadaf Ebrahimi
3136*b7893ccfSSadaf Ebrahimi for (uint32_t order_i = 0; order_i < customSampleOrderCount; ++order_i) {
3137*b7893ccfSSadaf Ebrahimi skip |= ValidateCoarseSampleOrderCustomNV(&pCustomSampleOrders[order_i]);
3138*b7893ccfSSadaf Ebrahimi }
3139*b7893ccfSSadaf Ebrahimi
3140*b7893ccfSSadaf Ebrahimi return skip;
3141*b7893ccfSSadaf Ebrahimi }
3142*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer,uint32_t taskCount,uint32_t firstTask)3143*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksNV(VkCommandBuffer commandBuffer, uint32_t taskCount,
3144*b7893ccfSSadaf Ebrahimi uint32_t firstTask) {
3145*b7893ccfSSadaf Ebrahimi bool skip = false;
3146*b7893ccfSSadaf Ebrahimi
3147*b7893ccfSSadaf Ebrahimi if (taskCount > phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount) {
3148*b7893ccfSSadaf Ebrahimi skip |= log_msg(
3149*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3150*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksNV-taskCount-02119",
3151*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksNV() parameter, uint32_t taskCount (0x%" PRIxLEAST32
3152*b7893ccfSSadaf Ebrahimi "), must be less than or equal to VkPhysicalDeviceMeshShaderPropertiesNV::maxDrawMeshTasksCount (0x%" PRIxLEAST32 ").",
3153*b7893ccfSSadaf Ebrahimi taskCount, phys_dev_ext_props.mesh_shader_props.maxDrawMeshTasksCount);
3154*b7893ccfSSadaf Ebrahimi }
3155*b7893ccfSSadaf Ebrahimi
3156*b7893ccfSSadaf Ebrahimi return skip;
3157*b7893ccfSSadaf Ebrahimi }
3158*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)3159*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
3160*b7893ccfSSadaf Ebrahimi VkDeviceSize offset, uint32_t drawCount,
3161*b7893ccfSSadaf Ebrahimi uint32_t stride) {
3162*b7893ccfSSadaf Ebrahimi bool skip = false;
3163*b7893ccfSSadaf Ebrahimi static const int condition_multiples = 0b0011;
3164*b7893ccfSSadaf Ebrahimi if (offset & condition_multiples) {
3165*b7893ccfSSadaf Ebrahimi skip |= log_msg(
3166*b7893ccfSSadaf Ebrahimi report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3167*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-offset-02710",
3168*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksIndirectNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64 "), is not a multiple of 4.", offset);
3169*b7893ccfSSadaf Ebrahimi }
3170*b7893ccfSSadaf Ebrahimi if (drawCount > 1 && ((stride & condition_multiples) || stride < sizeof(VkDrawMeshTasksIndirectCommandNV))) {
3171*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3172*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02146",
3173*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksIndirectNV() parameter, uint32_t stride (0x%" PRIxLEAST32
3174*b7893ccfSSadaf Ebrahimi "), is not a multiple of 4 or smaller than sizeof (VkDrawMeshTasksIndirectCommandNV).",
3175*b7893ccfSSadaf Ebrahimi stride);
3176*b7893ccfSSadaf Ebrahimi }
3177*b7893ccfSSadaf Ebrahimi if (!physical_device_features.multiDrawIndirect && ((drawCount > 1))) {
3178*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3179*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectNV-drawCount-02718",
3180*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksIndirectNV(): Device feature multiDrawIndirect disabled: count must be 0 or 1 but is %d",
3181*b7893ccfSSadaf Ebrahimi drawCount);
3182*b7893ccfSSadaf Ebrahimi }
3183*b7893ccfSSadaf Ebrahimi
3184*b7893ccfSSadaf Ebrahimi return skip;
3185*b7893ccfSSadaf Ebrahimi }
3186*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkBuffer countBuffer,VkDeviceSize countBufferOffset,uint32_t maxDrawCount,uint32_t stride)3187*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdDrawMeshTasksIndirectCountNV(VkCommandBuffer commandBuffer, VkBuffer buffer,
3188*b7893ccfSSadaf Ebrahimi VkDeviceSize offset, VkBuffer countBuffer,
3189*b7893ccfSSadaf Ebrahimi VkDeviceSize countBufferOffset,
3190*b7893ccfSSadaf Ebrahimi uint32_t maxDrawCount, uint32_t stride) {
3191*b7893ccfSSadaf Ebrahimi bool skip = false;
3192*b7893ccfSSadaf Ebrahimi
3193*b7893ccfSSadaf Ebrahimi if (offset & 3) {
3194*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3195*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-offset-02710",
3196*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize offset (0x%" PRIxLEAST64
3197*b7893ccfSSadaf Ebrahimi "), is not a multiple of 4.",
3198*b7893ccfSSadaf Ebrahimi offset);
3199*b7893ccfSSadaf Ebrahimi }
3200*b7893ccfSSadaf Ebrahimi
3201*b7893ccfSSadaf Ebrahimi if (countBufferOffset & 3) {
3202*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3203*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdDrawMeshTasksIndirectCountNV-countBufferOffset-02716",
3204*b7893ccfSSadaf Ebrahimi "vkCmdDrawMeshTasksIndirectCountNV() parameter, VkDeviceSize countBufferOffset (0x%" PRIxLEAST64
3205*b7893ccfSSadaf Ebrahimi "), is not a multiple of 4.",
3206*b7893ccfSSadaf Ebrahimi countBufferOffset);
3207*b7893ccfSSadaf Ebrahimi }
3208*b7893ccfSSadaf Ebrahimi
3209*b7893ccfSSadaf Ebrahimi return skip;
3210*b7893ccfSSadaf Ebrahimi }
3211*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateQueryPool(VkDevice device,const VkQueryPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkQueryPool * pQueryPool)3212*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo *pCreateInfo,
3213*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
3214*b7893ccfSSadaf Ebrahimi bool skip = false;
3215*b7893ccfSSadaf Ebrahimi
3216*b7893ccfSSadaf Ebrahimi // Validation for parameters excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
3217*b7893ccfSSadaf Ebrahimi if (pCreateInfo != nullptr) {
3218*b7893ccfSSadaf Ebrahimi // If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of
3219*b7893ccfSSadaf Ebrahimi // VkQueryPipelineStatisticFlagBits values
3220*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->queryType == VK_QUERY_TYPE_PIPELINE_STATISTICS) && (pCreateInfo->pipelineStatistics != 0) &&
3221*b7893ccfSSadaf Ebrahimi ((pCreateInfo->pipelineStatistics & (~AllVkQueryPipelineStatisticFlagBits)) != 0)) {
3222*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
3223*b7893ccfSSadaf Ebrahimi "VUID-VkQueryPoolCreateInfo-queryType-00792",
3224*b7893ccfSSadaf Ebrahimi "vkCreateQueryPool(): if pCreateInfo->queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, "
3225*b7893ccfSSadaf Ebrahimi "pCreateInfo->pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits "
3226*b7893ccfSSadaf Ebrahimi "values.");
3227*b7893ccfSSadaf Ebrahimi }
3228*b7893ccfSSadaf Ebrahimi }
3229*b7893ccfSSadaf Ebrahimi return skip;
3230*b7893ccfSSadaf Ebrahimi }
3231*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pPropertyCount,VkExtensionProperties * pProperties)3232*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
3233*b7893ccfSSadaf Ebrahimi const char *pLayerName, uint32_t *pPropertyCount,
3234*b7893ccfSSadaf Ebrahimi VkExtensionProperties *pProperties) {
3235*b7893ccfSSadaf Ebrahimi return validate_array("vkEnumerateDeviceExtensionProperties", "pPropertyCount", "pProperties", pPropertyCount, &pProperties,
3236*b7893ccfSSadaf Ebrahimi true, false, false, kVUIDUndefined, "VUID-vkEnumerateDeviceExtensionProperties-pProperties-parameter");
3237*b7893ccfSSadaf Ebrahimi }
3238*b7893ccfSSadaf Ebrahimi
PostCallRecordCreateRenderPass(VkDevice device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass,VkResult result)3239*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordCreateRenderPass(VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
3240*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3241*b7893ccfSSadaf Ebrahimi VkResult result) {
3242*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) return;
3243*b7893ccfSSadaf Ebrahimi RecordRenderPass(*pRenderPass, pCreateInfo);
3244*b7893ccfSSadaf Ebrahimi }
3245*b7893ccfSSadaf Ebrahimi
PostCallRecordCreateRenderPass2KHR(VkDevice device,const VkRenderPassCreateInfo2KHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass,VkResult result)3246*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordCreateRenderPass2KHR(VkDevice device, const VkRenderPassCreateInfo2KHR *pCreateInfo,
3247*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass,
3248*b7893ccfSSadaf Ebrahimi VkResult result) {
3249*b7893ccfSSadaf Ebrahimi // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
3250*b7893ccfSSadaf Ebrahimi if (result != VK_SUCCESS) return;
3251*b7893ccfSSadaf Ebrahimi RecordRenderPass(*pRenderPass, pCreateInfo);
3252*b7893ccfSSadaf Ebrahimi }
3253*b7893ccfSSadaf Ebrahimi
PostCallRecordDestroyRenderPass(VkDevice device,VkRenderPass renderPass,const VkAllocationCallbacks * pAllocator)3254*b7893ccfSSadaf Ebrahimi void StatelessValidation::PostCallRecordDestroyRenderPass(VkDevice device, VkRenderPass renderPass,
3255*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator) {
3256*b7893ccfSSadaf Ebrahimi // Track the state necessary for checking vkCreateGraphicsPipeline (subpass usage of depth and color attachments)
3257*b7893ccfSSadaf Ebrahimi std::unique_lock<std::mutex> lock(renderpass_map_mutex);
3258*b7893ccfSSadaf Ebrahimi renderpasses_states.erase(renderPass);
3259*b7893ccfSSadaf Ebrahimi }
3260*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateAllocateMemory(VkDevice device,const VkMemoryAllocateInfo * pAllocateInfo,const VkAllocationCallbacks * pAllocator,VkDeviceMemory * pMemory)3261*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateAllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
3262*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
3263*b7893ccfSSadaf Ebrahimi bool skip = false;
3264*b7893ccfSSadaf Ebrahimi
3265*b7893ccfSSadaf Ebrahimi if (pAllocateInfo) {
3266*b7893ccfSSadaf Ebrahimi auto chained_prio_struct = lvl_find_in_chain<VkMemoryPriorityAllocateInfoEXT>(pAllocateInfo->pNext);
3267*b7893ccfSSadaf Ebrahimi if (chained_prio_struct && (chained_prio_struct->priority < 0.0f || chained_prio_struct->priority > 1.0f)) {
3268*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
3269*b7893ccfSSadaf Ebrahimi "VUID-VkMemoryPriorityAllocateInfoEXT-priority-02602",
3270*b7893ccfSSadaf Ebrahimi "priority (=%f) must be between `0` and `1`, inclusive.", chained_prio_struct->priority);
3271*b7893ccfSSadaf Ebrahimi }
3272*b7893ccfSSadaf Ebrahimi }
3273*b7893ccfSSadaf Ebrahimi return skip;
3274*b7893ccfSSadaf Ebrahimi }
3275*b7893ccfSSadaf Ebrahimi
ValidateGeometryTrianglesNV(const VkGeometryTrianglesNV & triangles,VkDebugReportObjectTypeEXT object_type,uint64_t object_handle,const char * func_name) const3276*b7893ccfSSadaf Ebrahimi bool StatelessValidation::ValidateGeometryTrianglesNV(const VkGeometryTrianglesNV &triangles,
3277*b7893ccfSSadaf Ebrahimi VkDebugReportObjectTypeEXT object_type, uint64_t object_handle,
3278*b7893ccfSSadaf Ebrahimi const char *func_name) const {
3279*b7893ccfSSadaf Ebrahimi bool skip = false;
3280*b7893ccfSSadaf Ebrahimi
3281*b7893ccfSSadaf Ebrahimi if (triangles.vertexFormat != VK_FORMAT_R32G32B32_SFLOAT && triangles.vertexFormat != VK_FORMAT_R16G16B16_SFLOAT &&
3282*b7893ccfSSadaf Ebrahimi triangles.vertexFormat != VK_FORMAT_R16G16B16_SNORM && triangles.vertexFormat != VK_FORMAT_R32G32_SFLOAT &&
3283*b7893ccfSSadaf Ebrahimi triangles.vertexFormat != VK_FORMAT_R16G16_SFLOAT && triangles.vertexFormat != VK_FORMAT_R16G16_SNORM) {
3284*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3285*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-vertexFormat-02430", "%s", func_name);
3286*b7893ccfSSadaf Ebrahimi } else {
3287*b7893ccfSSadaf Ebrahimi uint32_t vertex_component_size = 0;
3288*b7893ccfSSadaf Ebrahimi if (triangles.vertexFormat == VK_FORMAT_R32G32B32_SFLOAT || triangles.vertexFormat == VK_FORMAT_R32G32_SFLOAT) {
3289*b7893ccfSSadaf Ebrahimi vertex_component_size = 4;
3290*b7893ccfSSadaf Ebrahimi } else if (triangles.vertexFormat == VK_FORMAT_R16G16B16_SFLOAT || triangles.vertexFormat == VK_FORMAT_R16G16B16_SNORM ||
3291*b7893ccfSSadaf Ebrahimi triangles.vertexFormat == VK_FORMAT_R16G16_SFLOAT || triangles.vertexFormat == VK_FORMAT_R16G16_SNORM) {
3292*b7893ccfSSadaf Ebrahimi vertex_component_size = 2;
3293*b7893ccfSSadaf Ebrahimi }
3294*b7893ccfSSadaf Ebrahimi if (vertex_component_size > 0 && SafeModulo(triangles.vertexOffset, vertex_component_size) != 0) {
3295*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3296*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-vertexOffset-02429", "%s", func_name);
3297*b7893ccfSSadaf Ebrahimi }
3298*b7893ccfSSadaf Ebrahimi }
3299*b7893ccfSSadaf Ebrahimi
3300*b7893ccfSSadaf Ebrahimi if (triangles.indexType != VK_INDEX_TYPE_UINT32 && triangles.indexType != VK_INDEX_TYPE_UINT16 &&
3301*b7893ccfSSadaf Ebrahimi triangles.indexType != VK_INDEX_TYPE_NONE_NV) {
3302*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3303*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-indexType-02433", "%s", func_name);
3304*b7893ccfSSadaf Ebrahimi } else {
3305*b7893ccfSSadaf Ebrahimi uint32_t index_element_size = 0;
3306*b7893ccfSSadaf Ebrahimi if (triangles.indexType == VK_INDEX_TYPE_UINT32) {
3307*b7893ccfSSadaf Ebrahimi index_element_size = 4;
3308*b7893ccfSSadaf Ebrahimi } else if (triangles.indexType == VK_INDEX_TYPE_UINT16) {
3309*b7893ccfSSadaf Ebrahimi index_element_size = 2;
3310*b7893ccfSSadaf Ebrahimi }
3311*b7893ccfSSadaf Ebrahimi if (index_element_size > 0 && SafeModulo(triangles.indexOffset, index_element_size) != 0) {
3312*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3313*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-indexOffset-02432", "%s", func_name);
3314*b7893ccfSSadaf Ebrahimi }
3315*b7893ccfSSadaf Ebrahimi }
3316*b7893ccfSSadaf Ebrahimi if (triangles.indexType == VK_INDEX_TYPE_NONE_NV) {
3317*b7893ccfSSadaf Ebrahimi if (triangles.indexCount != 0) {
3318*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3319*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-indexCount-02436", "%s", func_name);
3320*b7893ccfSSadaf Ebrahimi }
3321*b7893ccfSSadaf Ebrahimi if (triangles.indexData != VK_NULL_HANDLE) {
3322*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3323*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-indexData-02434", "%s", func_name);
3324*b7893ccfSSadaf Ebrahimi }
3325*b7893ccfSSadaf Ebrahimi }
3326*b7893ccfSSadaf Ebrahimi
3327*b7893ccfSSadaf Ebrahimi if (SafeModulo(triangles.transformOffset, 16) != 0) {
3328*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3329*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryTrianglesNV-transformOffset-02438", "%s", func_name);
3330*b7893ccfSSadaf Ebrahimi }
3331*b7893ccfSSadaf Ebrahimi
3332*b7893ccfSSadaf Ebrahimi return skip;
3333*b7893ccfSSadaf Ebrahimi }
3334*b7893ccfSSadaf Ebrahimi
ValidateGeometryAABBNV(const VkGeometryAABBNV & aabbs,VkDebugReportObjectTypeEXT object_type,uint64_t object_handle,const char * func_name) const3335*b7893ccfSSadaf Ebrahimi bool StatelessValidation::ValidateGeometryAABBNV(const VkGeometryAABBNV &aabbs, VkDebugReportObjectTypeEXT object_type,
3336*b7893ccfSSadaf Ebrahimi uint64_t object_handle, const char *func_name) const {
3337*b7893ccfSSadaf Ebrahimi bool skip = false;
3338*b7893ccfSSadaf Ebrahimi
3339*b7893ccfSSadaf Ebrahimi if (SafeModulo(aabbs.offset, 8) != 0) {
3340*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3341*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryAABBNV-offset-02440", "%s", func_name);
3342*b7893ccfSSadaf Ebrahimi }
3343*b7893ccfSSadaf Ebrahimi if (SafeModulo(aabbs.stride, 8) != 0) {
3344*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3345*b7893ccfSSadaf Ebrahimi "VUID-VkGeometryAABBNV-stride-02441", "%s", func_name);
3346*b7893ccfSSadaf Ebrahimi }
3347*b7893ccfSSadaf Ebrahimi
3348*b7893ccfSSadaf Ebrahimi return skip;
3349*b7893ccfSSadaf Ebrahimi }
3350*b7893ccfSSadaf Ebrahimi
ValidateGeometryNV(const VkGeometryNV & geometry,VkDebugReportObjectTypeEXT object_type,uint64_t object_handle,const char * func_name) const3351*b7893ccfSSadaf Ebrahimi bool StatelessValidation::ValidateGeometryNV(const VkGeometryNV &geometry, VkDebugReportObjectTypeEXT object_type,
3352*b7893ccfSSadaf Ebrahimi uint64_t object_handle, const char *func_name) const {
3353*b7893ccfSSadaf Ebrahimi bool skip = false;
3354*b7893ccfSSadaf Ebrahimi if (geometry.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_NV) {
3355*b7893ccfSSadaf Ebrahimi skip = ValidateGeometryTrianglesNV(geometry.geometry.triangles, object_type, object_handle, func_name);
3356*b7893ccfSSadaf Ebrahimi } else if (geometry.geometryType == VK_GEOMETRY_TYPE_AABBS_NV) {
3357*b7893ccfSSadaf Ebrahimi skip = ValidateGeometryAABBNV(geometry.geometry.aabbs, object_type, object_handle, func_name);
3358*b7893ccfSSadaf Ebrahimi }
3359*b7893ccfSSadaf Ebrahimi return skip;
3360*b7893ccfSSadaf Ebrahimi }
3361*b7893ccfSSadaf Ebrahimi
ValidateAccelerationStructureInfoNV(const VkAccelerationStructureInfoNV & info,VkDebugReportObjectTypeEXT object_type,uint64_t object_handle,const char * func_name) const3362*b7893ccfSSadaf Ebrahimi bool StatelessValidation::ValidateAccelerationStructureInfoNV(const VkAccelerationStructureInfoNV &info,
3363*b7893ccfSSadaf Ebrahimi VkDebugReportObjectTypeEXT object_type, uint64_t object_handle,
3364*b7893ccfSSadaf Ebrahimi const char *func_name) const {
3365*b7893ccfSSadaf Ebrahimi bool skip = false;
3366*b7893ccfSSadaf Ebrahimi if (info.type == VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV && info.geometryCount != 0) {
3367*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3368*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-type-02425",
3369*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: If type is VK_ACCELERATION_STRUCTURE_TYPE_TOP_LEVEL_NV then "
3370*b7893ccfSSadaf Ebrahimi "geometryCount must be 0.");
3371*b7893ccfSSadaf Ebrahimi }
3372*b7893ccfSSadaf Ebrahimi if (info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV && info.instanceCount != 0) {
3373*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3374*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-type-02426",
3375*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: If type is VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV then "
3376*b7893ccfSSadaf Ebrahimi "instanceCount must be 0.");
3377*b7893ccfSSadaf Ebrahimi }
3378*b7893ccfSSadaf Ebrahimi if (info.flags & VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV &&
3379*b7893ccfSSadaf Ebrahimi info.flags & VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV) {
3380*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3381*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-flags-02592",
3382*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: If flags has the VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_NV"
3383*b7893ccfSSadaf Ebrahimi "bit set, then it must not have the VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_BUILD_BIT_NV bit set.");
3384*b7893ccfSSadaf Ebrahimi }
3385*b7893ccfSSadaf Ebrahimi if (info.geometryCount > phys_dev_ext_props.ray_tracing_props.maxGeometryCount) {
3386*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3387*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-geometryCount-02422",
3388*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: geometryCount must be less than or equal to "
3389*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceRayTracingPropertiesNV::maxGeometryCount.");
3390*b7893ccfSSadaf Ebrahimi }
3391*b7893ccfSSadaf Ebrahimi if (info.instanceCount > phys_dev_ext_props.ray_tracing_props.maxInstanceCount) {
3392*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3393*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-instanceCount-02423",
3394*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: instanceCount must be less than or equal to "
3395*b7893ccfSSadaf Ebrahimi "VkPhysicalDeviceRayTracingPropertiesNV::maxInstanceCount.");
3396*b7893ccfSSadaf Ebrahimi }
3397*b7893ccfSSadaf Ebrahimi if (info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV && info.geometryCount > 0) {
3398*b7893ccfSSadaf Ebrahimi uint64_t total_triangle_count = 0;
3399*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < info.geometryCount; i++) {
3400*b7893ccfSSadaf Ebrahimi const VkGeometryNV &geometry = info.pGeometries[i];
3401*b7893ccfSSadaf Ebrahimi
3402*b7893ccfSSadaf Ebrahimi skip |= ValidateGeometryNV(geometry, object_type, object_handle, func_name);
3403*b7893ccfSSadaf Ebrahimi
3404*b7893ccfSSadaf Ebrahimi if (geometry.geometryType != VK_GEOMETRY_TYPE_TRIANGLES_NV) {
3405*b7893ccfSSadaf Ebrahimi continue;
3406*b7893ccfSSadaf Ebrahimi }
3407*b7893ccfSSadaf Ebrahimi total_triangle_count += geometry.geometry.triangles.indexCount / 3;
3408*b7893ccfSSadaf Ebrahimi }
3409*b7893ccfSSadaf Ebrahimi if (total_triangle_count > phys_dev_ext_props.ray_tracing_props.maxTriangleCount) {
3410*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle,
3411*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureInfoNV-maxTriangleCount-02424",
3412*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: The total number of triangles in all geometries must be less than "
3413*b7893ccfSSadaf Ebrahimi "or equal to VkPhysicalDeviceRayTracingPropertiesNV::maxTriangleCount.");
3414*b7893ccfSSadaf Ebrahimi }
3415*b7893ccfSSadaf Ebrahimi }
3416*b7893ccfSSadaf Ebrahimi if (info.type == VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_NV && info.geometryCount > 1) {
3417*b7893ccfSSadaf Ebrahimi const VkGeometryTypeNV first_geometry_type = info.pGeometries[0].geometryType;
3418*b7893ccfSSadaf Ebrahimi for (uint32_t i = 1; i < info.geometryCount; i++) {
3419*b7893ccfSSadaf Ebrahimi const VkGeometryNV &geometry = info.pGeometries[i];
3420*b7893ccfSSadaf Ebrahimi if (geometry.geometryType != first_geometry_type) {
3421*b7893ccfSSadaf Ebrahimi // TODO: update fake VUID below with the real one once it is generated.
3422*b7893ccfSSadaf Ebrahimi skip |=
3423*b7893ccfSSadaf Ebrahimi log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT,
3424*b7893ccfSSadaf Ebrahimi 0, "UNASSIGNED-VkAccelerationStructureInfoNV-pGeometries-XXXX",
3425*b7893ccfSSadaf Ebrahimi "VkAccelerationStructureInfoNV: info.pGeometries[%d].geometryType does not match "
3426*b7893ccfSSadaf Ebrahimi "info.pGeometries[0].geometryType.",
3427*b7893ccfSSadaf Ebrahimi i);
3428*b7893ccfSSadaf Ebrahimi }
3429*b7893ccfSSadaf Ebrahimi }
3430*b7893ccfSSadaf Ebrahimi }
3431*b7893ccfSSadaf Ebrahimi return skip;
3432*b7893ccfSSadaf Ebrahimi }
3433*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateAccelerationStructureNV(VkDevice device,const VkAccelerationStructureCreateInfoNV * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkAccelerationStructureNV * pAccelerationStructure)3434*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateAccelerationStructureNV(
3435*b7893ccfSSadaf Ebrahimi VkDevice device, const VkAccelerationStructureCreateInfoNV *pCreateInfo, const VkAllocationCallbacks *pAllocator,
3436*b7893ccfSSadaf Ebrahimi VkAccelerationStructureNV *pAccelerationStructure) {
3437*b7893ccfSSadaf Ebrahimi bool skip = false;
3438*b7893ccfSSadaf Ebrahimi
3439*b7893ccfSSadaf Ebrahimi if (pCreateInfo) {
3440*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->compactedSize != 0) &&
3441*b7893ccfSSadaf Ebrahimi ((pCreateInfo->info.geometryCount != 0) || (pCreateInfo->info.instanceCount != 0))) {
3442*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
3443*b7893ccfSSadaf Ebrahimi "VUID-VkAccelerationStructureCreateInfoNV-compactedSize-02421",
3444*b7893ccfSSadaf Ebrahimi "vkCreateAccelerationStructureNV(): pCreateInfo->compactedSize nonzero (%" PRIu64
3445*b7893ccfSSadaf Ebrahimi ") with info.geometryCount (%" PRIu32 ") or info.instanceCount (%" PRIu32 ") nonzero.",
3446*b7893ccfSSadaf Ebrahimi pCreateInfo->compactedSize, pCreateInfo->info.geometryCount, pCreateInfo->info.instanceCount);
3447*b7893ccfSSadaf Ebrahimi }
3448*b7893ccfSSadaf Ebrahimi
3449*b7893ccfSSadaf Ebrahimi skip |= ValidateAccelerationStructureInfoNV(pCreateInfo->info, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT, 0,
3450*b7893ccfSSadaf Ebrahimi "vkCreateAccelerationStructureNV()");
3451*b7893ccfSSadaf Ebrahimi }
3452*b7893ccfSSadaf Ebrahimi
3453*b7893ccfSSadaf Ebrahimi return skip;
3454*b7893ccfSSadaf Ebrahimi }
3455*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdBuildAccelerationStructureNV(VkCommandBuffer commandBuffer,const VkAccelerationStructureInfoNV * pInfo,VkBuffer instanceData,VkDeviceSize instanceOffset,VkBool32 update,VkAccelerationStructureNV dst,VkAccelerationStructureNV src,VkBuffer scratch,VkDeviceSize scratchOffset)3456*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdBuildAccelerationStructureNV(
3457*b7893ccfSSadaf Ebrahimi VkCommandBuffer commandBuffer, const VkAccelerationStructureInfoNV *pInfo, VkBuffer instanceData, VkDeviceSize instanceOffset,
3458*b7893ccfSSadaf Ebrahimi VkBool32 update, VkAccelerationStructureNV dst, VkAccelerationStructureNV src, VkBuffer scratch, VkDeviceSize scratchOffset) {
3459*b7893ccfSSadaf Ebrahimi bool skip = false;
3460*b7893ccfSSadaf Ebrahimi
3461*b7893ccfSSadaf Ebrahimi if (pInfo != nullptr) {
3462*b7893ccfSSadaf Ebrahimi skip |= ValidateAccelerationStructureInfoNV(*pInfo, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT,
3463*b7893ccfSSadaf Ebrahimi HandleToUint64(dst), "vkCmdBuildAccelerationStructureNV()");
3464*b7893ccfSSadaf Ebrahimi }
3465*b7893ccfSSadaf Ebrahimi
3466*b7893ccfSSadaf Ebrahimi return skip;
3467*b7893ccfSSadaf Ebrahimi }
3468*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateGetAccelerationStructureHandleNV(VkDevice device,VkAccelerationStructureNV accelerationStructure,size_t dataSize,void * pData)3469*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateGetAccelerationStructureHandleNV(VkDevice device,
3470*b7893ccfSSadaf Ebrahimi VkAccelerationStructureNV accelerationStructure,
3471*b7893ccfSSadaf Ebrahimi size_t dataSize, void *pData) {
3472*b7893ccfSSadaf Ebrahimi bool skip = false;
3473*b7893ccfSSadaf Ebrahimi if (dataSize < 8) {
3474*b7893ccfSSadaf Ebrahimi skip = log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_ACCELERATION_STRUCTURE_NV_EXT,
3475*b7893ccfSSadaf Ebrahimi HandleToUint64(accelerationStructure), "VUID-vkGetAccelerationStructureHandleNV-dataSize-02240",
3476*b7893ccfSSadaf Ebrahimi "vkGetAccelerationStructureHandleNV(): dataSize must be greater than or equal to 8.");
3477*b7893ccfSSadaf Ebrahimi }
3478*b7893ccfSSadaf Ebrahimi return skip;
3479*b7893ccfSSadaf Ebrahimi }
3480*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateRayTracingPipelinesNV(VkDevice device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkRayTracingPipelineCreateInfoNV * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)3481*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateRayTracingPipelinesNV(VkDevice device, VkPipelineCache pipelineCache,
3482*b7893ccfSSadaf Ebrahimi uint32_t createInfoCount,
3483*b7893ccfSSadaf Ebrahimi const VkRayTracingPipelineCreateInfoNV *pCreateInfos,
3484*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
3485*b7893ccfSSadaf Ebrahimi VkPipeline *pPipelines) {
3486*b7893ccfSSadaf Ebrahimi bool skip = false;
3487*b7893ccfSSadaf Ebrahimi
3488*b7893ccfSSadaf Ebrahimi for (uint32_t i = 0; i < createInfoCount; i++) {
3489*b7893ccfSSadaf Ebrahimi auto feedback_struct = lvl_find_in_chain<VkPipelineCreationFeedbackCreateInfoEXT>(pCreateInfos[i].pNext);
3490*b7893ccfSSadaf Ebrahimi if ((feedback_struct != nullptr) && (feedback_struct->pipelineStageCreationFeedbackCount != pCreateInfos[i].stageCount)) {
3491*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, VK_NULL_HANDLE,
3492*b7893ccfSSadaf Ebrahimi "VUID-VkPipelineCreationFeedbackCreateInfoEXT-pipelineStageCreationFeedbackCount-02670",
3493*b7893ccfSSadaf Ebrahimi "vkCreateRayTracingPipelinesNV(): in pCreateInfo[%" PRIu32
3494*b7893ccfSSadaf Ebrahimi "], VkPipelineCreationFeedbackEXT::pipelineStageCreationFeedbackCount"
3495*b7893ccfSSadaf Ebrahimi "(=%" PRIu32 ") must equal VkRayTracingPipelineCreateInfoNV::stageCount(=%" PRIu32 ").",
3496*b7893ccfSSadaf Ebrahimi i, feedback_struct->pipelineStageCreationFeedbackCount, pCreateInfos[i].stageCount);
3497*b7893ccfSSadaf Ebrahimi }
3498*b7893ccfSSadaf Ebrahimi }
3499*b7893ccfSSadaf Ebrahimi
3500*b7893ccfSSadaf Ebrahimi return skip;
3501*b7893ccfSSadaf Ebrahimi }
3502*b7893ccfSSadaf Ebrahimi
3503*b7893ccfSSadaf Ebrahimi #ifdef VK_USE_PLATFORM_WIN32_KHR
PreCallValidateGetDeviceGroupSurfacePresentModes2EXT(VkDevice device,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkDeviceGroupPresentModeFlagsKHR * pModes)3504*b7893ccfSSadaf Ebrahimi bool StatelessValidation::PreCallValidateGetDeviceGroupSurfacePresentModes2EXT(VkDevice device,
3505*b7893ccfSSadaf Ebrahimi const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo,
3506*b7893ccfSSadaf Ebrahimi VkDeviceGroupPresentModeFlagsKHR *pModes) {
3507*b7893ccfSSadaf Ebrahimi bool skip = false;
3508*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_khr_swapchain)
3509*b7893ccfSSadaf Ebrahimi skip |= OutputExtensionError("vkGetDeviceGroupSurfacePresentModes2EXT", VK_KHR_SWAPCHAIN_EXTENSION_NAME);
3510*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_khr_get_surface_capabilities_2)
3511*b7893ccfSSadaf Ebrahimi skip |= OutputExtensionError("vkGetDeviceGroupSurfacePresentModes2EXT", VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME);
3512*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_khr_surface)
3513*b7893ccfSSadaf Ebrahimi skip |= OutputExtensionError("vkGetDeviceGroupSurfacePresentModes2EXT", VK_KHR_SURFACE_EXTENSION_NAME);
3514*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_khr_get_physical_device_properties_2)
3515*b7893ccfSSadaf Ebrahimi skip |=
3516*b7893ccfSSadaf Ebrahimi OutputExtensionError("vkGetDeviceGroupSurfacePresentModes2EXT", VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
3517*b7893ccfSSadaf Ebrahimi if (!device_extensions.vk_ext_full_screen_exclusive)
3518*b7893ccfSSadaf Ebrahimi skip |= OutputExtensionError("vkGetDeviceGroupSurfacePresentModes2EXT", VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME);
3519*b7893ccfSSadaf Ebrahimi skip |= validate_struct_type(
3520*b7893ccfSSadaf Ebrahimi "vkGetDeviceGroupSurfacePresentModes2EXT", "pSurfaceInfo", "VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR",
3521*b7893ccfSSadaf Ebrahimi pSurfaceInfo, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, true,
3522*b7893ccfSSadaf Ebrahimi "VUID-vkGetDeviceGroupSurfacePresentModes2EXT-pSurfaceInfo-parameter", "VUID-VkPhysicalDeviceSurfaceInfo2KHR-sType-sType");
3523*b7893ccfSSadaf Ebrahimi if (pSurfaceInfo != NULL) {
3524*b7893ccfSSadaf Ebrahimi const VkStructureType allowed_structs_VkPhysicalDeviceSurfaceInfo2KHR[] = {
3525*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT,
3526*b7893ccfSSadaf Ebrahimi VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_WIN32_INFO_EXT};
3527*b7893ccfSSadaf Ebrahimi
3528*b7893ccfSSadaf Ebrahimi skip |= validate_struct_pnext("vkGetDeviceGroupSurfacePresentModes2EXT", "pSurfaceInfo->pNext",
3529*b7893ccfSSadaf Ebrahimi "VkSurfaceFullScreenExclusiveInfoEXT, VkSurfaceFullScreenExclusiveWin32InfoEXT",
3530*b7893ccfSSadaf Ebrahimi pSurfaceInfo->pNext, ARRAY_SIZE(allowed_structs_VkPhysicalDeviceSurfaceInfo2KHR),
3531*b7893ccfSSadaf Ebrahimi allowed_structs_VkPhysicalDeviceSurfaceInfo2KHR, GeneratedVulkanHeaderVersion,
3532*b7893ccfSSadaf Ebrahimi "VUID-VkPhysicalDeviceSurfaceInfo2KHR-pNext-pNext");
3533*b7893ccfSSadaf Ebrahimi
3534*b7893ccfSSadaf Ebrahimi skip |= validate_required_handle("vkGetDeviceGroupSurfacePresentModes2EXT", "pSurfaceInfo->surface", pSurfaceInfo->surface);
3535*b7893ccfSSadaf Ebrahimi }
3536*b7893ccfSSadaf Ebrahimi return skip;
3537*b7893ccfSSadaf Ebrahimi }
3538*b7893ccfSSadaf Ebrahimi #endif
3539*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCreateFramebuffer(VkDevice device,const VkFramebufferCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkFramebuffer * pFramebuffer)3540*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
3541*b7893ccfSSadaf Ebrahimi const VkAllocationCallbacks *pAllocator,
3542*b7893ccfSSadaf Ebrahimi VkFramebuffer *pFramebuffer) {
3543*b7893ccfSSadaf Ebrahimi // Validation for pAttachments which is excluded from the generated validation code due to a 'noautovalidity' tag in vk.xml
3544*b7893ccfSSadaf Ebrahimi bool skip = false;
3545*b7893ccfSSadaf Ebrahimi if ((pCreateInfo->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT_KHR) == 0) {
3546*b7893ccfSSadaf Ebrahimi skip |= validate_array("vkCreateFramebuffer", "attachmentCount", "pAttachments", pCreateInfo->attachmentCount,
3547*b7893ccfSSadaf Ebrahimi &pCreateInfo->pAttachments, false, true, kVUIDUndefined, kVUIDUndefined);
3548*b7893ccfSSadaf Ebrahimi }
3549*b7893ccfSSadaf Ebrahimi return skip;
3550*b7893ccfSSadaf Ebrahimi }
3551*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdSetLineStippleEXT(VkCommandBuffer commandBuffer,uint32_t lineStippleFactor,uint16_t lineStipplePattern)3552*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdSetLineStippleEXT(VkCommandBuffer commandBuffer, uint32_t lineStippleFactor,
3553*b7893ccfSSadaf Ebrahimi uint16_t lineStipplePattern) {
3554*b7893ccfSSadaf Ebrahimi bool skip = false;
3555*b7893ccfSSadaf Ebrahimi
3556*b7893ccfSSadaf Ebrahimi if (lineStippleFactor < 1 || lineStippleFactor > 256) {
3557*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3558*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdSetLineStippleEXT-lineStippleFactor-02776",
3559*b7893ccfSSadaf Ebrahimi "vkCmdSetLineStippleEXT::lineStippleFactor=%d is not in [1,256].", lineStippleFactor);
3560*b7893ccfSSadaf Ebrahimi }
3561*b7893ccfSSadaf Ebrahimi
3562*b7893ccfSSadaf Ebrahimi return skip;
3563*b7893ccfSSadaf Ebrahimi }
3564*b7893ccfSSadaf Ebrahimi
manual_PreCallValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer,VkBuffer buffer,VkDeviceSize offset,VkIndexType indexType)3565*b7893ccfSSadaf Ebrahimi bool StatelessValidation::manual_PreCallValidateCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer,
3566*b7893ccfSSadaf Ebrahimi VkDeviceSize offset, VkIndexType indexType) {
3567*b7893ccfSSadaf Ebrahimi bool skip = false;
3568*b7893ccfSSadaf Ebrahimi
3569*b7893ccfSSadaf Ebrahimi if (indexType == VK_INDEX_TYPE_NONE_NV) {
3570*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3571*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdBindIndexBuffer-indexType-02507",
3572*b7893ccfSSadaf Ebrahimi "vkCmdBindIndexBuffer() indexType must not be VK_INDEX_TYPE_NONE_NV.");
3573*b7893ccfSSadaf Ebrahimi }
3574*b7893ccfSSadaf Ebrahimi
3575*b7893ccfSSadaf Ebrahimi const auto *index_type_uint8_features =
3576*b7893ccfSSadaf Ebrahimi lvl_find_in_chain<VkPhysicalDeviceIndexTypeUint8FeaturesEXT>(physical_device_features2.pNext);
3577*b7893ccfSSadaf Ebrahimi if (indexType == VK_INDEX_TYPE_UINT8_EXT && !index_type_uint8_features->indexTypeUint8) {
3578*b7893ccfSSadaf Ebrahimi skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
3579*b7893ccfSSadaf Ebrahimi HandleToUint64(commandBuffer), "VUID-vkCmdBindIndexBuffer-indexType-02765",
3580*b7893ccfSSadaf Ebrahimi "vkCmdBindIndexBuffer() indexType is VK_INDEX_TYPE_UINT8_EXT but indexTypeUint8 feature is not enabled.");
3581*b7893ccfSSadaf Ebrahimi }
3582*b7893ccfSSadaf Ebrahimi
3583*b7893ccfSSadaf Ebrahimi return skip;
3584*b7893ccfSSadaf Ebrahimi }
3585