diff options
| author | Mark Lobodzinski <mark@lunarg.com> | 2017-03-27 11:52:02 -0600 |
|---|---|---|
| committer | Mark Lobodzinski <mark@lunarg.com> | 2017-03-28 08:58:45 -0600 |
| commit | 6a7928215b88e94f48a017f08adae570d69aae3e (patch) | |
| tree | 5bd2cbe28ed9b4f43a55fa12893ca5e0ad66a4c4 /layers/parameter_validation_utils.h | |
| parent | 1126795edad0190e808ef27df94b24344bf3b358 (diff) | |
| download | usermoji-6a7928215b88e94f48a017f08adae570d69aae3e.tar.xz | |
layers: Add pNext cycle/redundancy checks to PV
Change-Id: I06d311821ef0c10683ad8bdaf076231143cde22f
Diffstat (limited to 'layers/parameter_validation_utils.h')
| -rw-r--r-- | layers/parameter_validation_utils.h | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/layers/parameter_validation_utils.h b/layers/parameter_validation_utils.h index 842268f0..dd67a72e 100644 --- a/layers/parameter_validation_utils.h +++ b/layers/parameter_validation_utils.h @@ -491,12 +491,17 @@ static bool validate_struct_pnext(debug_report_data *report_data, const char *ap const char *allowed_struct_names, const void *next, size_t allowed_type_count, const VkStructureType *allowed_types, uint32_t header_version) { bool skip_call = false; + std::unordered_set<const void *> cycle_check; + std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check; + const char disclaimer[] = "This warning is based on the Valid Usage documentation for version %d of the Vulkan header. It " "is possible that you are using a struct from a private extension or an extension that was added " "to a later version of the Vulkan header, in which case your use of %s is perfectly valid but " "is not guaranteed to work correctly with validation enabled"; + // TODO: The valid pNext structure types are not recursive. Each structure has its own list of valid sTypes for pNext. + // Codegen a map of vectors containing the allowable pNext types for each struct and use that here -- also simplifies parms. if (next != NULL) { if (allowed_type_count == 0) { std::string message = "%s: value of %s must be NULL. "; @@ -509,10 +514,31 @@ static bool validate_struct_pnext(debug_report_data *report_data, const char *ap const VkStructureType *end = allowed_types + allowed_type_count; const GenericHeader *current = reinterpret_cast<const GenericHeader *>(next); + cycle_check.insert(next); + + while (current != NULL) { - if (std::find(start, end, current->sType) == end) { - std::string type_name = string_VkStructureType(current->sType); + if (cycle_check.find(current->pNext) != cycle_check.end()) { + std::string message = "%s: %s chain contains a cycle -- pNext pointer " PRIx64 " is repeated."; + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name, + parameter_name.get_name().c_str(), reinterpret_cast<uint64_t>(next)); + break; + } else { + cycle_check.insert(current->pNext); + } + std::string type_name = string_VkStructureType(current->sType); + if (unique_stype_check.find(current->sType) != unique_stype_check.end()) { + std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times."; + skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, + __LINE__, INVALID_STRUCT_PNEXT, LayerName, message.c_str(), api_name, + parameter_name.get_name().c_str(), type_name.c_str()); + } else { + unique_stype_check.insert(current->sType); + } + + if (std::find(start, end, current->sType) == end) { if (type_name == UnsupportedStructureTypeString) { std::string message = "%s: %s chain includes a structure with unexpected VkStructureType (%d); Allowed " @@ -532,7 +558,6 @@ static bool validate_struct_pnext(debug_report_data *report_data, const char *ap header_version, parameter_name.get_name().c_str()); } } - current = reinterpret_cast<const GenericHeader *>(current->pNext); } } |
