layers: eradicate remaining VUID enums
Improved format stripping of error text strings in vk_validation_stats
script and added functionality to export a new header file that
maps text VUIDs to these spec error strings. Removed lingering
references to UNIQUE_VALIDATION_ERROR_CODE enums and functions that
were still passing (now unused) msg_code parameters.
Updated CMakeLists to avoid build errors on Win64 related to the size
of the new error map.
Change-Id: I1ff74c7b57ce5021271842da5419055820bd4730
diff --git a/scripts/vk_validation_stats.py b/scripts/vk_validation_stats.py
index 5b87be4..faacdf3 100755
--- a/scripts/vk_validation_stats.py
+++ b/scripts/vk_validation_stats.py
@@ -37,7 +37,7 @@
txt_filename = "validation_error_database.txt"
csv_filename = "validation_error_database.csv"
html_filename = "validation_error_database.html"
-# header_file = '../layers/vk_validation_error_messages.h'
+header_filename = "../layers/vk_validation_error_messages.h"
test_file = '../tests/layer_validation_tests.cpp'
vuid_prefixes = ['VUID-', 'UNASSIGNED-']
@@ -64,6 +64,7 @@
'../layers/buffer_validation.cpp',
]
+# This needs to be updated as new extensions roll in
khr_aliases = {
'VUID-vkBindBufferMemory2KHR-device-parameter' : 'VUID-vkBindBufferMemory2-device-parameter',
'VUID-vkBindBufferMemory2KHR-pBindInfos-parameter' : 'VUID-vkBindBufferMemory2-pBindInfos-parameter',
@@ -142,6 +143,7 @@
print (" [ -text [ <text_out_filename>] ]")
print (" [ -csv [ <csv_out_filename>] ]")
print (" [ -html [ <html_out_filename>] ]")
+ print (" [ -export_header ]")
print (" [ -verbose ]")
print (" [ -help ]")
print ("\n The vk_validation_stats script parses validation layer source files to")
@@ -159,6 +161,7 @@
print (" defaults to 'validation_error_database.csv'")
print (" -html [filename] output the error database in html to <html_database_filename>,")
print (" defaults to 'validation_error_database.html'")
+ print (" -export_header export a new VUID error text header file to <%s>" % header_filename)
print (" -verbose show your work (to stdout)")
class ValidationJSON:
@@ -169,13 +172,22 @@
self.all_vuids = set()
self.vuid_db = defaultdict(list) # Maps VUID string to list of json-data dicts
self.apiversion = ""
- self.re_striptags = re.compile('<.*?>|&(amp;)+lt;|&(amp;)+gt;')
self.duplicate_vuids = set()
+
+ # A set of specific regular expression substitutions needed to clean up VUID text
+ self.regex_dict = {}
+ self.regex_dict[re.compile('<.*?>|&(amp;)+lt;|&(amp;)+gt;')] = ""
+ self.regex_dict[re.compile(r'\\\(codeSize \\over 4\\\)')] = "(codeSize/4)"
+ self.regex_dict[re.compile(r'\\\(\\lceil\{\\mathit\{rasterizationSamples} \\over 32}\\rceil\\\)')] = "(rasterizationSamples/32)"
+ # Some fancy punctuation chars that break the Android build...
+ self.regex_dict[re.compile('→')] = "->" # Arrow char
+ self.regex_dict[re.compile('’')] = "'" # Left-slanting apostrophe to apostrophe
+ self.regex_dict[re.compile('̶(0|1);')] = "'" # L/R-slanting quotes to apostrophe
def read(self):
self.json_dict = {}
if os.path.isfile(self.filename):
- json_file = open(self.filename, 'r')
+ json_file = open(self.filename, 'r', encoding='utf-8')
self.json_dict = json.load(json_file)
json_file.close()
if len(self.json_dict) == 0:
@@ -204,15 +216,15 @@
self.implicit_vuids.add(vuid_string) # otherwise, implicit
vtype = 'implicit'
vuid_text = ventry['text']
- #if 'amp;' in vuid_text:
- # print(vuid_text)
- stripped = re.sub(self.re_striptags, '', vuid_text) # strip tags & literals
- stripped = html.unescape(stripped) # anything missed by the regex
- #if 'amp;' in stripped:
- # print(" %s" % stripped)
- self.vuid_db[vuid_string].append({'api':apiname, 'ext':ext, 'type':vtype, 'text':stripped})
+ for regex, replacement in self.regex_dict.items():
+ vuid_text = re.sub(regex, replacement, vuid_text) # do regex substitution
+ vuid_text = html.unescape(vuid_text) # anything missed by the regex
+ self.vuid_db[vuid_string].append({'api':apiname, 'ext':ext, 'type':vtype, 'text':vuid_text})
self.all_vuids = self.explicit_vuids | self.implicit_vuids
self.duplicate_vuids = set({v for v in self.vuid_db if len(self.vuid_db[v]) > 1})
+ if len(self.duplicate_vuids) > 0:
+ print("Warning: duplicate VUIDs found in validusage.json")
+
class ValidationSource:
def __init__(self, source_file_list, generated_source_file_list, generated_source_directories):
@@ -452,6 +464,47 @@
self.vj = val_json
self.vs = val_source
self.vt = val_tests
+ self.header_preamble = """/* THIS FILE IS GENERATED. DO NOT EDIT. */
+/* (scripts/vk_validation_stats.py) */
+/*
+ * Vulkan
+ *
+ * Copyright (c) 2016-2018 Google Inc.
+ * Copyright (c) 2016-2018 LunarG, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Dave Houlton <daveh@lunarg.com>
+ */
+
+#pragma once
+
+// Disable auto-formatting for generated file
+// clang-format off
+
+#include <string>
+#include <unordered_map>
+
+// Mapping from VUID string to the corresponding spec text
+#ifdef VALIDATION_ERROR_MAP_IMPL
+std::unordered_map<std::string, std::string> vuid_to_error_text_map {
+"""
+ self.header_postamble = """};
+#else
+extern std::unordered_map<std::string, std::string> vuid_to_error_text_map;
+#endif"""
+ self.spec_url = "https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html"
def dump_txt(self):
print("\n Dumping database to text file: %s" % txt_filename)
@@ -528,6 +581,21 @@
hfile.write('<th>%s</th></tr>\n' % db_entry['text'])
hfile.write('</table>\n</body>\n</html>\n')
+ def export_header(self):
+ print("\n Exporting header file to: %s" % header_filename)
+ with open (header_filename, 'w') as hfile:
+ hfile.write(self.header_preamble)
+ vuid_list = list(self.vj.all_vuids)
+ vuid_list.sort()
+ for vuid in vuid_list:
+ db_entry = self.vj.vuid_db[vuid][0]
+ hfile.write(' {"%s", "%s (%s#%s)"},\n' % (vuid, db_entry['text'].strip(' '), self.spec_url, vuid))
+ # For multiply-defined VUIDs, include versions with extension appended
+ if len(self.vj.vuid_db[vuid]) > 1:
+ for db_entry in self.vj.vuid_db[vuid]:
+ hfile.write(' {"%s[%s]", "%s (%s#%s)"},\n' % (vuid, db_entry['ext'].strip(' '), db_entry['text'].strip(' '), self.spec_url, vuid))
+ hfile.write(self.header_postamble)
+
def main(argv):
global verbose_mode
global txt_filename
@@ -540,6 +608,7 @@
txt_out = False
csv_out = False
html_out = False
+ header_out = False
if (1 > len(argv)):
printHelp()
@@ -576,6 +645,8 @@
if i < len(argv) and not argv[i].startswith('-'):
html_filename = argv[i]
i = i + 1
+ elif (arg == '-export_header'):
+ header_out = True
elif (arg in ['-verbose']):
verbose_mode = True
elif (arg in ['-help', '-h']):
@@ -700,7 +771,8 @@
db_out.dump_csv()
if html_out:
db_out.dump_html()
-
+ if header_out:
+ db_out.export_header()
return result
if __name__ == "__main__":