scripts: Offline codegen vk_validation_stats.py

- Move vk_validation_error_messages.h to generated dir
- Remove build directory (generated) code paths from VUID search
- Make script able to function with any cwd by getting the repo root and
  using absolute paths for source files
- Add the split layer test files to fix test coverage

Change-Id: I6dc424b5b4a54583a1b34c0c394ed6f44c7fdb88
diff --git a/scripts/vk_validation_stats.py b/scripts/vk_validation_stats.py
index ca6dbf1..f4ab2ce 100755
--- a/scripts/vk_validation_stats.py
+++ b/scripts/vk_validation_stats.py
@@ -39,8 +39,7 @@
 txt_filename = "validation_error_database.txt"
 csv_filename = "validation_error_database.csv"
 html_filename = "validation_error_database.html"
-header_filename = "../layers/vk_validation_error_messages.h"
-test_file = '../tests/layer_validation_tests.cpp'
+header_filename = "vk_validation_error_messages.h"
 vuid_prefixes = ['VUID-', 'UNASSIGNED-']
 
 # Hard-coded flags that could be command line args, if we decide that's useful
@@ -48,26 +47,32 @@
 dealias_khr = True
 ignore_unassigned = True # These are not found in layer code unless they appear explicitly (most don't), so produce false positives
 
-generated_layer_source_directories = [
-'build',
-'dbuild',
-'release',
-'../build/Vulkan-ValidationLayers/'
-]
-generated_layer_source_files = [
-'parameter_validation.cpp',
-'object_tracker.cpp',
-]
-layer_source_files = [
-'../layers/buffer_validation.cpp',
-'../layers/core_validation.cpp',
-'../layers/descriptor_sets.cpp',
-'../layers/drawdispatch.cpp',
-'../layers/parameter_validation_utils.cpp',
-'../layers/object_tracker_utils.cpp',
-'../layers/shader_validation.cpp',
-'../layers/stateless_validation.h'
-]
+# helper to define paths relative to this file
+def script_relative(path):
+    return os.path.abspath(os.path.join(os.path.dirname(__file__), path))
+
+layer_source_files = [script_relative(path) for path in [
+    '../layers/buffer_validation.cpp',
+    '../layers/core_validation.cpp',
+    '../layers/descriptor_sets.cpp',
+    '../layers/drawdispatch.cpp',
+    '../layers/parameter_validation_utils.cpp',
+    '../layers/object_tracker_utils.cpp',
+    '../layers/shader_validation.cpp',
+    '../layers/stateless_validation.h',
+    '../layers/generated/parameter_validation.cpp',
+    '../layers/generated/object_tracker.cpp',
+]]
+
+test_source_files = [script_relative(path) for path in [
+    '../tests/layer_validation_tests.cpp',
+    '../tests/vklayertests_buffer_image_memory_sampler.cpp',
+    '../tests/vklayertests_command.cpp',
+    '../tests/vklayertests_descriptor_renderpass_framebuffer.cpp',
+    '../tests/vklayertests_others.cpp',
+    '../tests/vklayertests_pipeline_shader.cpp',
+    '../tests/vkpositivelayertests.cpp',
+]]
 
 # This needs to be updated as new extensions roll in
 khr_aliases = {
@@ -237,10 +242,8 @@
 
 
 class ValidationSource:
-    def __init__(self, source_file_list, generated_source_file_list, generated_source_directories):
+    def __init__(self, source_file_list):
         self.source_files = source_file_list
-        self.generated_source_files = generated_source_file_list
-        self.generated_source_dirs = generated_source_directories
         self.vuid_count_dict = {} # dict of vuid values to the count of how much they're used, and location of where they're used
         self.duplicated_checks = 0
         self.explicit_vuids = set()
@@ -248,22 +251,6 @@
         self.unassigned_vuids = set()
         self.all_vuids = set()
 
-        if len(self.generated_source_files) > 0:
-            qualified_paths = []
-            for source in self.generated_source_files:
-                for build_dir in self.generated_source_dirs:
-                    filepath = '../%s/layers/%s' % (build_dir, source)
-                    if os.path.isfile(filepath):
-                        qualified_paths.append(filepath)
-                        break
-            if len(self.generated_source_files) != len(qualified_paths):
-                print("Error: Unable to locate one or more of the following source files in the %s directories" % (", ".join(generated_source_directories)))
-                print(self.generated_source_files)
-                print("Failed to locate one or more codegen files in layer source code - cannot proceed.")
-                exit(1)
-            else:
-                self.source_files.extend(qualified_paths)
-
     def parse(self):
         prepend = None
         for sf in self.source_files:
@@ -478,7 +465,6 @@
         self.vt = val_tests
         self.header_version = "/* THIS FILE IS GENERATED - DO NOT EDIT (scripts/vk_validation_stats.py) */"
         self.header_version += "\n/* Vulkan specification version: %s */" % val_json.apiversion
-        self.header_version += "\n/* Header generated: %s */\n" % time.strftime('%Y-%m-%d %H:%M:%S')
         self.header_preamble = """
 /*
  * Vulkan
@@ -724,7 +710,7 @@
                     print("    with extension: %s" % ext['ext'])
 
     # Parse layer source files
-    val_source = ValidationSource(layer_source_files, generated_layer_source_files, generated_layer_source_directories)
+    val_source = ValidationSource(layer_source_files)
     val_source.parse()
     exp_checks = len(val_source.explicit_vuids)
     imp_checks = len(val_source.implicit_vuids)
@@ -737,13 +723,13 @@
         print("  %d checks are implemented more that once" % val_source.duplicated_checks)
 
     # Parse test files
-    val_tests = ValidationTests([test_file, ])
+    val_tests = ValidationTests(test_source_files)
     val_tests.parse()
     exp_tests = len(val_tests.explicit_vuids)
     imp_tests = len(val_tests.implicit_vuids)
     all_tests = len(val_tests.all_vuids)
     if verbose_mode:
-        print("Found %d unique error vuids in test file %s." % (all_tests, test_file))
+        print("Found %d unique error vuids in test source code." % all_tests)
         print("  %d explicit" % exp_tests)
         print("  %d implicit" % imp_tests)
         print("  %d unassigned" % len(val_tests.unassigned_vuids))