MCPcopy Create free account
hub / github.com/KhronosGroup/Vulkan-ValidationLayers / ValidateStructPnext

Method ValidateStructPnext

layers/stateless/sl_utils.cpp:234–306  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

232}
233
234bool Context::ValidateStructPnext(const Location& loc, const void* next, size_t allowed_type_count,
235 const VkStructureType* allowed_types, uint32_t header_version, const char* pnext_vuid,
236 const char* stype_vuid, const bool is_const_param) const {
237 bool skip = false;
238
239 if (HasCustomStypeInfo()) {
240 return skip;
241 }
242
243 if (next != nullptr) {
244 vvl::unordered_set<const void*> cycle_check;
245 vvl::unordered_set<VkStructureType, vvl::hash<int>> unique_stype_check;
246 const char* disclaimer =
247 "This error is based on the Valid Usage documentation for version %" PRIu32
248 " of the Vulkan header. It is possible that "
249 "you are using a struct from a private extension or an extension that was added to a later version of the Vulkan "
250 "header, in which case the use of %s is undefined and may not work correctly with validation enabled";
251
252 const Location pNext_loc = loc.dot(Field::pNext);
253 if (allowed_type_count == 0) {
254 std::string message = "must be NULL.\n";
255 message += disclaimer;
256 skip |=
257 log.LogError(pnext_vuid, error_obj.handle, pNext_loc, message.c_str(), header_version, pNext_loc.Fields().c_str());
258 } else {
259 const VkStructureType* start = allowed_types;
260 const VkStructureType* end = allowed_types + allowed_type_count;
261 const VkBaseOutStructure* current = reinterpret_cast<const VkBaseOutStructure*>(next);
262
263 while (current != nullptr) {
264 if ((loc.function != Func::vkCreateInstance || (current->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)) &&
265 (loc.function != Func::vkCreateDevice || (current->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) {
266 if (unique_stype_check.find(current->sType) != unique_stype_check.end() && !IsDuplicatePnext(current->sType)) {
267 // stype_vuid will only be null if there are no listed pNext and will hit disclaimer check
268 skip |= log.LogError(stype_vuid, error_obj.handle, pNext_loc,
269 "chain contains duplicate structure types: %s appears multiple times.\n%s",
270 string_VkStructureName(current->sType), PrintPNextChain(loc.structure, next).c_str());
271 } else {
272 unique_stype_check.insert(current->sType);
273 }
274
275 if (std::find(start, end, current->sType) == end) {
276 const std::string type_name = string_VkStructureType(current->sType);
277 if (type_name.compare("Unhandled VkStructureType") == 0) {
278 std::string message = "chain includes a structure with unknown VkStructureType (%" PRIu32 ").\n%s\n";
279 message += disclaimer;
280 skip |= log.LogError(pnext_vuid, error_obj.handle, pNext_loc, message.c_str(), current->sType,
281 PrintPNextChain(Struct::Empty, next).c_str(), header_version,
282 pNext_loc.Fields().c_str());
283 } else {
284 std::string message = "chain includes a structure with unexpected VkStructureType %s.\n%s\n";
285 message += disclaimer;
286 skip |= log.LogError(pnext_vuid, error_obj.handle, pNext_loc, message.c_str(), type_name.c_str(),
287 PrintPNextChain(Struct::Empty, next).c_str(), header_version,
288 pNext_loc.Fields().c_str());
289 }
290 }
291 // Send Location without pNext field so the pNext() connector can be used

Calls 8

PrintPNextChainFunction · 0.85
dotMethod · 0.80
LogErrorMethod · 0.80
c_strMethod · 0.80
FieldsMethod · 0.80
findMethod · 0.45
endMethod · 0.45
insertMethod · 0.45

Tested by

no test coverage detected