Merge remote-tracking branch 'aosp/upstream-android_layers' into 20161108-merge-android_layers_to_master
diff --git a/.gitignore b/.gitignore
index 2ff8e41..6eceb39 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,8 +13,6 @@
 out32/*
 out64/*
 demos/Debug/*
-demos/tri.dir/Debug/*
-demos/tri/Debug/*
 demos/Win32/Debug/*
 demos/xcb_nvidia.dir/*
 demos/smoke/HelpersDispatchTable.cpp
diff --git a/BUILD.md b/BUILD.md
index f79aff3..8087cfd 100644
--- a/BUILD.md
+++ b/BUILD.md
@@ -58,6 +58,45 @@
 describes both how ICDs and layers should be properly
 packaged, and how developers can point to ICDs and layers within their builds.
 
+### Linux Install to System Directories
+
+Installing the files resulting from your build to the systems directories is optional since
+environment variables can usually be used instead to locate the binaries.
+There are also risks with interfering with binaries installed by packages.
+If you are certain that you would like to install your binaries to system directories,
+you can proceed with these instructions.
+
+Assuming that you've built the code as described above and the current directory is still `dbuild`,
+you can execute:
+
+```
+sudo make install
+```
+
+This command installs files to:
+
+* `/usr/local/include/vulkan`:  Vulkan include files
+* `/usr/local/lib`:  Vulkan loader and layers shared objects
+* `/usr/local/bin`:  vulkaninfo application
+* `/etc/vulkan/explicit_layer.d`:  Layer JSON files
+
+You may need to run `ldconfig` in order to refresh the system loader search cache on some Linux systems.
+
+The list of installed files appears in the build directory in a file named `install_manifest.txt`.
+You can easily remove the installed files with:
+
+```
+cat install_manifest.txt | sudo xargs rm
+```
+
+See the CMake documentation for details on using `DESTDIR` and `CMAKE_INSTALL_PREFIX` to customize
+your installation location.
+
+Note that some executables in this repository (e.g., `cube`) use the "rpath" linker directive
+to load the Vulkan loader from the build directory, `dbuild` in this example.
+This means that even after installing the loader to the system directories, these executables
+still use the loader from the build directory.
+
 ## Validation Test
 
 The test executables can be found in the dbuild/tests directory. 
@@ -71,7 +110,6 @@
 
 Some demos that can be found in the dbuild/demos directory are:
 - vulkaninfo: report GPU properties
-- tri: a textured triangle (which is animated to demonstrate Z-clipping)
 - cube: a textured spinning cube
 - smoke/smoke: A "smoke" test using a more complex Vulkan demo
 
@@ -179,6 +217,36 @@
 android-generate.bat
 ndk-build
 ```
+#### Android demos
+Use the following steps to build, install, and run Cube and Tri for Android:
+```
+cd demos/android
+android update project -s -p . -t "android-23"
+ndk-build
+ant -buildfile cube debug
+adb install ./cube/bin/NativeActivity-debug.apk
+adb shell am start com.example.Cube/android.app.NativeActivity
+```
+To build, install, and run Cube with validation layers, first build layers using steps above, then run:
+```
+cd demos/android
+android update project -s -p . -t "android-23"
+ndk-build -j
+ant -buildfile cube-with-layers debug
+adb install ./cube-with-layers/bin/NativeActivity-debug.apk
+adb shell am start -a android.intent.action.MAIN -c android-intent.category.LAUNCH -n com.example.CubeWithLayers/android.app.NativeActivity --es args "--validate"
+```
+
+To build, install, and run the Smoke demo for Android, run the following, and any
+prompts that come back from the script:
+```
+./update_external_sources.sh --glslang
+cd demos/smoke/android
+export ANDROID_SDK_HOME=<path to Android/Sdk>
+export ANDROID_NDK_HOME=<path to Android/Sdk/ndk-bundle>
+./build-and-install
+adb shell am start com.example.Smoke/android.app.NativeActivity
+```
 
 #### Building with upstream sources
 ##### Linux and OSX
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ed5092..4b3fd13 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,8 +18,8 @@
     add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
     set(DisplayServer Android)
 elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-    #   Note: Supported configurations are XCB, XCB + Xlib, Wayland.  
-    #         MIR is stubbed and untested 
+    #   Note: Supported configurations are XCB, XCB + Xlib, Wayland.
+    #         MIR is stubbed and untested
     option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
     option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
     option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" OFF)
@@ -44,15 +44,15 @@
         add_definitions(-DVK_USE_PLATFORM_MIR_KHR)
         set(DisplayServer Mir)
     endif()
-    
+
     if (NOT BUILD_WSI_XCB_SUPPORT AND NOT BUILD_WSI_XLIB_SUPPORT AND NOT BUILD_WSI_WAYLAND_SUPPORT AND NOT BUILD_WSI_MIR_SUPPORT)
         set(DisplayServer Display)
-    endif()    
+    endif()
 else()
     message(FATAL_ERROR "Unsupported Platform!")
 endif()
 
-set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
 
 # Header file for CMake settings
 include_directories("${PROJECT_SOURCE_DIR}/include")
@@ -282,6 +282,10 @@
     endif()
 endif()
 
+if(UNIX)
+    install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/vulkan" DESTINATION include)
+endif()
+
 # loader: Generic VULKAN ICD loader
 # tests: VULKAN tests
 if(BUILD_LOADER)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index f721af1..160c9d2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -66,8 +66,6 @@
 
 >        cube
 >        cube --validate
->        tri
->        tri --validate
 >        smoke
 >        smoke --validate
 >        vulkaninfo
diff --git a/build-android/android-generate.bat b/build-android/android-generate.bat
index 7ef92de..0407d7f 100644
--- a/build-android/android-generate.bat
+++ b/build-android/android-generate.bat
@@ -24,8 +24,7 @@
 python ../vk_helper.py --gen_enum_string_helper ../include/vulkan/vulkan.h --abs_out_dir generated/include

 python ../vk_helper.py --gen_struct_wrappers ../include/vulkan/vulkan.h --abs_out_dir generated/include

 

-python ../vk-layer-generate.py Android unique_objects ../include/vulkan/vulkan.h > generated/include/unique_objects.cpp

-

 cd generated/include

-python ../../../genvk.py threading -registry ../../../vk.xml thread_check.h

-python ../../../genvk.py paramchecker -registry ../../../vk.xml parameter_validation.h

+python ../../../lvl_genvk.py -registry ../../../vk.xml thread_check.h

+python ../../../lvl_genvk.py -registry ../../../vk.xml parameter_validation.h

+python ../../../lvl_genvk.py -registry ../../../vk.xml unique_objects_wrappers.h

diff --git a/build-android/android-generate.sh b/build-android/android-generate.sh
index dadf6dd..d4da421 100755
--- a/build-android/android-generate.sh
+++ b/build-android/android-generate.sh
@@ -26,8 +26,8 @@
 python ../vk_helper.py --gen_enum_string_helper ../include/vulkan/vulkan.h --abs_out_dir generated/include
 python ../vk_helper.py --gen_struct_wrappers ../include/vulkan/vulkan.h --abs_out_dir generated/include
 
-python ../vk-layer-generate.py Android unique_objects ../include/vulkan/vulkan.h > generated/include/unique_objects.cpp
-( cd generated/include; python ../../../genvk.py threading -registry ../../../vk.xml thread_check.h )
-( cd generated/include; python ../../../genvk.py paramchecker -registry ../../../vk.xml parameter_validation.h )
+( cd generated/include; python ../../../lvl_genvk.py -registry ../../../vk.xml thread_check.h )
+( cd generated/include; python ../../../lvl_genvk.py -registry ../../../vk.xml parameter_validation.h )
+( cd generated/include; python ../../../lvl_genvk.py -registry ../../../vk.xml unique_objects_wrappers.h )
 
 exit 0
diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
index 610cdf9..77629e0 100644
--- a/build-android/jni/Android.mk
+++ b/build-android/jni/Android.mk
@@ -31,7 +31,7 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/layers \
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -46,8 +46,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils glslang SPIRV-Tools
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -60,8 +62,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -74,8 +78,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -88,8 +94,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -102,13 +110,15 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
 LOCAL_MODULE := VkLayer_unique_objects
-LOCAL_SRC_FILES += $(LAYER_DIR)/include/unique_objects.cpp
+LOCAL_SRC_FILES += $(SRC_DIR)/layers/unique_objects.cpp
 LOCAL_SRC_FILES += $(LAYER_DIR)/include/vk_safe_struct.cpp
 LOCAL_SRC_FILES += $(SRC_DIR)/layers/vk_layer_table.cpp
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SRC_DIR)/include \
@@ -117,8 +127,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
@@ -131,8 +143,10 @@
                     $(LOCAL_PATH)/$(SRC_DIR)/loader
 LOCAL_STATIC_LIBRARIES += layer_utils
 LOCAL_CPPFLAGS += -std=c++11 -Wall -Werror -Wno-unused-function -Wno-unused-const-variable -mxgot
-LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES
+LOCAL_CPPFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR -DVK_PROTOTYPES -fvisibility=hidden
 LOCAL_LDLIBS    := -llog
+LOCAL_LDFLAGS   += -Wl,-Bsymbolic
+LOCAL_LDFLAGS   += -Wl,--exclude-libs,ALL
 include $(BUILD_SHARED_LIBRARY)
 
 $(call import-module,android/native_app_glue)
diff --git a/build_windows_targets.bat b/build_windows_targets.bat
index e60d3bb..11a9ba7 100644
--- a/build_windows_targets.bat
+++ b/build_windows_targets.bat
@@ -71,7 +71,7 @@
     echo Generating 64-bit CMake files for Visual Studio %VS_VERSION%
     cmake -G "Visual Studio %VS_VERSION% Win64" ..
     echo Building 64-bit Debug 
-    msbuild ALL_BUILD.vcxproj /p:Platform=x64 /p:Configuration=Debug /verbosity:quiet
+    msbuild ALL_BUILD.vcxproj /p:Platform=x64 /p:Configuration=Debug /maxcpucount /verbosity:quiet
     if errorlevel 1 (
        echo.
        echo 64-bit Debug build failed!
@@ -80,7 +80,7 @@
     )   
    
     echo Building 64-bit Release 
-    msbuild ALL_BUILD.vcxproj /p:Platform=x64 /p:Configuration=Release /verbosity:quiet
+    msbuild ALL_BUILD.vcxproj /p:Platform=x64 /p:Configuration=Release /maxcpucount /verbosity:quiet
     if errorlevel 1 (
        echo.
        echo 64-bit Release build failed!
@@ -101,7 +101,7 @@
     echo Generating 32-bit CMake files for Visual Studio %VS_VERSION%
     cmake -G "Visual Studio %VS_VERSION%" ..
     echo Building 32-bit Debug 
-    msbuild ALL_BUILD.vcxproj /p:Platform=x86 /p:Configuration=Debug /verbosity:quiet
+    msbuild ALL_BUILD.vcxproj /p:Platform=x86 /p:Configuration=Debug /maxcpucount /verbosity:quiet
     if errorlevel 1 (
        echo.
        echo 32-bit Debug build failed!
@@ -110,7 +110,7 @@
     )   
        
     echo Building 32-bit Release 
-    msbuild ALL_BUILD.vcxproj /p:Platform=x86 /p:Configuration=Release /verbosity:quiet
+    msbuild ALL_BUILD.vcxproj /p:Platform=x86 /p:Configuration=Release /maxcpucount /verbosity:quiet
     if errorlevel 1 (
        echo.
        echo 32-bit Release build failed!
diff --git a/cmake/FindImageMagick.cmake b/cmake/FindImageMagick.cmake
index ccf0a01..2d765bc 100644
--- a/cmake/FindImageMagick.cmake
+++ b/cmake/FindImageMagick.cmake
@@ -91,16 +91,16 @@
         GET_FILENAME_COMPONENT(IM_BIN_PATH  
           [HKEY_LOCAL_MACHINE\\SOFTWARE\\ImageMagick\\Current;BinPath]
           ABSOLUTE CACHE)
-          
+
       # Otherwise, the WOW6432Node returned a string, assume 32-bit build on 64-bit OS and use that string.
       else()
 
         GET_FILENAME_COMPONENT(IM_BIN_PATH  
           [HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\ImageMagick\\Current;BinPath]
           ABSOLUTE CACHE)
-        
+
       endif()
-      
+
     endif()
 
     set (IMAGEMAGIC_REG_PATH ${IM_BIN_PATH} PARENT_SCOPE)
@@ -113,24 +113,32 @@
     set (IMAGEMAGIC_REG_PATH "" PARENT_SCOPE)
     set (IMAGEMAGIC_REGINCLUDE_PATH "" PARENT_SCOPE)
     set (IMAGEMAGIC_REGLIB_PATH "" PARENT_SCOPE)
-    
+
   endif()
+
 endfunction()
 
 
 #---------------------------------------------------------------------
 # Helper functions
 #---------------------------------------------------------------------
-FUNCTION(FIND_IMAGEMAGICK_API component header)
+FUNCTION(FIND_IMAGEMAGICK_API component path header)
   SET(ImageMagick_${component}_FOUND FALSE PARENT_SCOPE)
 
+  # NOTE: My experience is that Windows uses the PATHs
+  #       variables, while Linux uses the PATH_SUFFIXES.
+  #       You can't add sub-directories to the PATH_SUFFIXES
+  #       because it messes up the ImageMagick Include
+  #       paths that are returned.  Instead, you have to
+  #       call this FIND_IMAGEMAGICK_API for each separate
+  #       possible sub-folder.
   FIND_PATH(ImageMagick_${component}_INCLUDE_DIR
     NAMES ${header}
     PATHS
       ${ImageMagick_INCLUDE_DIRS}
       ${IMAGEMAGIC_REGINCLUDE_PATH}
     PATH_SUFFIXES
-      ImageMagick ImageMagick-6
+      ImageMagick ImageMagick-6 ImageMagick-7
     DOC "Path to the ImageMagick include dir."
     )
   FIND_PATH(ImageMagick_${component}_ARCH_INCLUDE_DIR
@@ -139,7 +147,7 @@
       ${ImageMagick_INCLUDE_DIRS}
       ${IMAGEMAGIC_REGINCLUDE_PATH}
     PATH_SUFFIXES
-      ImageMagick ImageMagick-6
+      ImageMagick ImageMagick-6 ImageMagick-7
     DOC "Path to the ImageMagick arch-specific include dir."
     )
   FIND_LIBRARY(ImageMagick_${component}_LIBRARY
@@ -149,17 +157,28 @@
     DOC "Path to the ImageMagick Magick++ library."
     )
 
-  IF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
 
+  IF (ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
     SET(ImageMagick_${component}_FOUND TRUE PARENT_SCOPE)
+
     LIST(APPEND ImageMagick_INCLUDE_DIRS
       ${ImageMagick_${component}_INCLUDE_DIR}
       )
-    IF(EXISTS ${ImageMagick_${component}_ARCH_INCLUDE_DIR})
+
+    # Only add the path if it's not the special string "<NONE>"
+    IF(NOT path STREQUAL "<NONE>")
+       LIST(APPEND ImageMagick_INCLUDE_DIRS
+         ${ImageMagick_${component}_INCLUDE_DIR}/${path}
+       )
+    ENDIF()
+
+    # Add the architecture include path if it exists
+    IF (ImageMagick_${component}_ARCH_INCLUDE_DIR)
       LIST(APPEND ImageMagick_INCLUDE_DIRS
         ${ImageMagick_${component}_ARCH_INCLUDE_DIR}
         )
-    ENDIF(EXISTS ${ImageMagick_${component}_ARCH_INCLUDE_DIR})
+    ENDIF()
+
     LIST(REMOVE_DUPLICATES ImageMagick_INCLUDE_DIRS)
     SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS} PARENT_SCOPE)
 
@@ -167,7 +186,7 @@
       ${ImageMagick_${component}_LIBRARY}
       )
     SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES} PARENT_SCOPE)
-  ENDIF(ImageMagick_${component}_INCLUDE_DIR AND ImageMagick_${component}_LIBRARY)
+  ENDIF()
 
 ENDFUNCTION(FIND_IMAGEMAGICK_API)
 
@@ -210,34 +229,92 @@
     # DEPRECATED: forced components for backward compatibility
     convert mogrify import montage composite
     )
-  IF(component STREQUAL "Magick++")
-    FIND_IMAGEMAGICK_API(Magick++ Magick++.h
-      Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8 Magick++-6.Q16HDRI Magick++-Q16HDRI Magick++-6.Q8HDRI Magick++-Q8HDRI
-      )
-  ELSEIF(component STREQUAL "MagickWand")
-    FIND_IMAGEMAGICK_API(MagickWand wand/MagickWand.h
-      Wand MagickWand CORE_RL_wand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI
-      )
-  ELSEIF(component STREQUAL "MagickCore")
-    FIND_IMAGEMAGICK_API(MagickCore magick/MagickCore.h
-      Magick MagickCore CORE_RL_magick_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8 MagickCore-6.Q16HDRI MagickCore-Q16HDRI MagickCore-6.Q8HDRI MagickCore-Q8HDRI
-      )
-  ELSE(component STREQUAL "Magick++")
-    IF(ImageMagick_EXECUTABLE_DIR)
-      FIND_IMAGEMAGICK_EXE(${component})
-    ENDIF(ImageMagick_EXECUTABLE_DIR)
-  ENDIF(component STREQUAL "Magick++")
-  
-  IF(NOT ImageMagick_${component}_FOUND)
-    LIST(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
-    IF(is_requested GREATER -1)
-      SET(ImageMagick_FOUND FALSE)
-    ENDIF(is_requested GREATER -1)
-  ENDIF(NOT ImageMagick_${component}_FOUND)
-ENDFOREACH(component)
 
-SET(ImageMagick_INCLUDE_DIRS ${ImageMagick_INCLUDE_DIRS})
-SET(ImageMagick_LIBRARIES ${ImageMagick_LIBRARIES})
+    IF(component STREQUAL "Magick++")
+        # unset cached variable that assumes header parameter never changes
+        UNSET(ImageMagick_MagickWand_INCLUDE_DIR CACHE)
+
+        # Try top folder first
+        FIND_IMAGEMAGICK_API(Magick++ <NONE> Magick++.h
+            Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8 Magick++-6.Q16HDRI Magick++-Q16HDRI Magick++-6.Q8HDRI Magick++-Q8HDRI
+        )
+
+        IF(NOT ImageMagick_Magick++_INCLUDE_DIR OR NOT ImageMagick_Magick++_LIBRARY)
+            # Look for Magick++.h, in the magick++ sub-folder
+            FIND_IMAGEMAGICK_API(Magick++ magick++ magick++/Magick++.h
+                Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8 Magick++-6.Q16HDRI Magick++-Q16HDRI Magick++-6.Q8HDRI Magick++-Q8HDRI
+            )
+        ENDIF()
+
+        IF(NOT ImageMagick_Magick++_INCLUDE_DIR OR NOT ImageMagick_Magick++_LIBRARY)
+            # Look for Magick++.h, in the magick sub-folder
+            FIND_IMAGEMAGICK_API(Magick++ magick magick/Magick++.h
+                Magick++ CORE_RL_Magick++_ Magick++-6.Q16 Magick++-Q16 Magick++-6.Q8 Magick++-Q8 Magick++-6.Q16HDRI Magick++-Q16HDRI Magick++-6.Q8HDRI Magick++-Q8HDRI
+            )
+        ENDIF()
+
+    ELSEIF(component STREQUAL "MagickWand")
+        # unset cached variable that assumes header parameter never changes
+        UNSET(ImageMagick_MagickWand_INCLUDE_DIR CACHE)
+
+        # Try top folder first
+        FIND_IMAGEMAGICK_API(MagickWand <NONE> MagickWand.h
+           Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI
+        )
+
+        IF(NOT ImageMagick_MagickWand_INCLUDE_DIR OR NOT ImageMagick_MagickWand_LIBRARY)
+            # Look for MagickWand.h in the wand sub-folder
+            FIND_IMAGEMAGICK_API(MagickWand wand wand/MagickWand.h
+              Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI
+            )
+        ENDIF()
+
+        IF(NOT ImageMagick_MagickWand_INCLUDE_DIR OR NOT ImageMagick_MagickWand_LIBRARY)
+            # Look for MagickWand.h he MagickWand sub-folder
+            FIND_IMAGEMAGICK_API(MagickWand MagickWand MagickWand/MagickWand.h
+              Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI
+            )
+        ENDIF()
+
+        IF(NOT ImageMagick_MagickWand_INCLUDE_DIR OR NOT ImageMagick_MagickWand_LIBRARY)
+            # Look for MagickWand.h he magick sub-folder
+            FIND_IMAGEMAGICK_API(MagickWand magick magick/MagickWand.h
+              Wand MagickWand CORE_RL_wand_ CORE_RL_MagickWand_ MagickWand-6.Q16 MagickWand-Q16 MagickWand-6.Q8 MagickWand-Q8 MagickWand-6.Q16HDRI MagickWand-Q16HDRI MagickWand-6.Q8HDRI MagickWand-Q8HDRI
+            )
+        ENDIF()
+
+    ELSEIF(component STREQUAL "MagickCore")
+
+        # Try top folder first
+        FIND_IMAGEMAGICK_API(MagickCore <NONE> MagickCore.h
+          Magick MagickCore CORE_RL_magick_ CORE_RL_MagickCore_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8 MagickCore-6.Q16HDRI MagickCore-Q16HDRI MagickCore-6.Q8HDRI MagickCore-Q8HDRI
+        )
+
+        IF(NOT ImageMagick_MagickCore_INCLUDE_DIR OR NOT ImageMagick_MagickCore_LIBRARY)
+            # Look for MagickCore.h, in the MagickCore sub-folder
+            FIND_IMAGEMAGICK_API(MagickCore MagickCore MagickCore/MagickCore.h
+              Magick MagickCore CORE_RL_magick_ CORE_RL_MagickCore_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8 MagickCore-6.Q16HDRI MagickCore-Q16HDRI MagickCore-6.Q8HDRI MagickCore-Q8HDRI
+            )
+        ENDIF()
+
+        IF(NOT ImageMagick_MagickCore_INCLUDE_DIR OR NOT ImageMagick_MagickCore_LIBRARY)
+            # Look for MagickCore.h, in the magick sub-folder
+            FIND_IMAGEMAGICK_API(MagickCore magick magick/MagickCore.h
+              Magick MagickCore CORE_RL_magick_ CORE_RL_MagickCore_ MagickCore-6.Q16 MagickCore-Q16 MagickCore-6.Q8 MagickCore-Q8 MagickCore-6.Q16HDRI MagickCore-Q16HDRI MagickCore-6.Q8HDRI MagickCore-Q8HDRI
+            )
+        ENDIF()
+
+    ENDIF()
+  
+    IF(NOT ImageMagick_${component}_FOUND)
+
+        LIST(FIND ImageMagick_FIND_COMPONENTS ${component} is_requested)
+        IF(is_requested GREATER -1)
+            SET(ImageMagick_FOUND FALSE)
+        ENDIF(is_requested GREATER -1)
+
+    ENDIF(NOT ImageMagick_${component}_FOUND)
+ENDFOREACH(component)
 
 #---------------------------------------------------------------------
 # Standard Package Output
@@ -264,7 +341,7 @@
     CACHE FILEPATH "Path to ImageMagick's montage executable.")
 SET(IMAGEMAGICK_COMPOSITE_EXECUTABLE ${ImageMagick_composite_EXECUTABLE}
     CACHE FILEPATH "Path to ImageMagick's composite executable.")
-    
+
 MARK_AS_ADVANCED(
   IMAGEMAGICK_BINARY_PATH
   IMAGEMAGICK_CONVERT_EXECUTABLE
diff --git a/common/android_util.cpp b/common/android_util.cpp
new file mode 100644
index 0000000..c2c4616
--- /dev/null
+++ b/common/android_util.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Google, 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.
+ *
+ * Relicensed from the WTFPL (http://www.wtfpl.net/faq/).
+ */
+
+#include "android_util.h"
+#include <android_native_app_glue.h>
+#include <cassert>
+#include <vector>
+#include <string>
+#include <sstream>
+
+extern "C" {
+
+// Convert Intents to arg list, returning argc and argv
+// Note that this C routine mallocs memory that the caller must free
+char** get_args(struct android_app* app, const char* intent_extra_data_key, const char* appTag, int* count)
+{
+    std::vector<std::string> args;
+    JavaVM &vm = *app->activity->vm;
+    JNIEnv *p_env;
+    if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
+        return nullptr;
+
+    JNIEnv &env = *p_env;
+    jobject activity = app->activity->clazz;
+    jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity),
+            "getIntent", "()Landroid/content/Intent;");
+    jobject intent = env.CallObjectMethod(activity, get_intent_method);
+    jmethodID get_string_extra_method = env.GetMethodID(env.GetObjectClass(intent),
+            "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
+    jvalue get_string_extra_args;
+    get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
+    jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent,
+            get_string_extra_method, &get_string_extra_args));
+
+    std::string args_str;
+    if (extra_str) {
+        const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
+        args_str = extra_utf;
+        env.ReleaseStringUTFChars(extra_str, extra_utf);
+        env.DeleteLocalRef(extra_str);
+    }
+
+    env.DeleteLocalRef(get_string_extra_args.l);
+    env.DeleteLocalRef(intent);
+    vm.DetachCurrentThread();
+
+    // split args_str
+    std::stringstream ss(args_str);
+    std::string arg;
+    while (std::getline(ss, arg, ' ')) {
+        if (!arg.empty())
+            args.push_back(arg);
+    }
+
+    // Convert our STL results to C friendly constructs
+    assert(count != nullptr);
+    *count = args.size() + 1;
+    char** vector = (char**) malloc(*count * sizeof(char*));
+    const char* appName = appTag ? appTag : (const char*) "appTag";
+
+   vector[0] = (char*) malloc(strlen(appName) * sizeof(char));
+   strcpy(vector[0], appName);
+
+    for (uint32_t i = 0; i < args.size(); i++) {
+        vector[i + 1] = (char*) malloc(strlen(args[i].c_str()) * sizeof(char));
+        strcpy(vector[i + 1], args[i].c_str());
+    }
+
+    return vector;
+}
+
+} // extern "C"
diff --git a/common/android_util.h b/common/android_util.h
new file mode 100644
index 0000000..666afff
--- /dev/null
+++ b/common/android_util.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016 Google, 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.
+ *
+ * Relicensed from the WTFPL (http://www.wtfpl.net/faq/).
+ */
+
+#ifndef ANDROID_UTIL_H
+#define ANDROID_UTIL_H
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+char** get_args(struct android_app* app, const char* intent_extra_data_key, const char* appTag, int* count);
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt
index 34ac6a7..c19c044 100644
--- a/demos/CMakeLists.txt
+++ b/demos/CMakeLists.txt
@@ -43,39 +43,18 @@
         endif()
     endforeach()
 
-    add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/tri-vert.spv
-       COMMAND ${GLSLANG_VALIDATOR} -s -V ${PROJECT_SOURCE_DIR}/demos/tri.vert
-       COMMAND move vert.spv ${CMAKE_BINARY_DIR}/demos/tri-vert.spv
-       DEPENDS tri.vert ${GLSLANG_VALIDATOR}
-       )
-    add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/tri-frag.spv
-       COMMAND ${GLSLANG_VALIDATOR} -s -V ${PROJECT_SOURCE_DIR}/demos/tri.frag
-       COMMAND move frag.spv ${CMAKE_BINARY_DIR}/demos/tri-frag.spv
-       DEPENDS tri.frag ${GLSLANG_VALIDATOR}
-       )
     add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/cube-vert.spv
-       COMMAND ${GLSLANG_VALIDATOR} -s -V ${PROJECT_SOURCE_DIR}/demos/cube.vert
-       COMMAND move vert.spv ${CMAKE_BINARY_DIR}/demos/cube-vert.spv
+       COMMAND ${GLSLANG_VALIDATOR} -s -V -o ${CMAKE_BINARY_DIR}/demos/cube-vert.spv ${PROJECT_SOURCE_DIR}/demos/cube.vert
        DEPENDS cube.vert ${GLSLANG_VALIDATOR}
        )
     add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/cube-frag.spv
-       COMMAND ${GLSLANG_VALIDATOR} -s -V ${PROJECT_SOURCE_DIR}/demos/cube.frag
-       COMMAND move frag.spv ${CMAKE_BINARY_DIR}/demos/cube-frag.spv
+       COMMAND ${GLSLANG_VALIDATOR} -s -V -o ${CMAKE_BINARY_DIR}/demos/cube-frag.spv ${PROJECT_SOURCE_DIR}/demos/cube.frag
        DEPENDS cube.frag ${GLSLANG_VALIDATOR}
        )
    file(COPY cube.vcxproj.user DESTINATION ${CMAKE_BINARY_DIR}/demos)
-   file(COPY tri.vcxproj.user DESTINATION ${CMAKE_BINARY_DIR}/demos)
    file(COPY vulkaninfo.vcxproj.user DESTINATION ${CMAKE_BINARY_DIR}/demos)
 else()
     if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
-        add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/tri-vert.spv
-            COMMAND ${GLSLANG_VALIDATOR} -s -V -o tri-vert.spv ${PROJECT_SOURCE_DIR}/demos/tri.vert 
-            DEPENDS tri.vert ${GLSLANG_VALIDATOR}
-            )
-        add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/tri-frag.spv
-            COMMAND ${GLSLANG_VALIDATOR} -s -V -o tri-frag.spv ${PROJECT_SOURCE_DIR}/demos/tri.frag
-            DEPENDS tri.frag ${GLSLANG_VALIDATOR}
-            )
         add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/demos/cube-vert.spv
             COMMAND ${GLSLANG_VALIDATOR} -s -V -o cube-vert.spv ${PROJECT_SOURCE_DIR}/demos/cube.vert
             DEPENDS cube.vert ${GLSLANG_VALIDATOR}
@@ -93,7 +72,7 @@
         link_libraries(${XCB_LIBRARIES})
     endif()
     if(BUILD_WSI_XLIB_SUPPORT)
-        include_directories(${X11_INCLUDE_DIRS})
+        include_directories(${X11_INCLUDE_DIR})
         link_libraries(${X11_LIBRARIES})
     endif()
     if(BUILD_WSI_WAYLAND_SUPPORT)
@@ -116,17 +95,6 @@
 add_executable(vulkaninfo vulkaninfo.c)
 target_link_libraries(vulkaninfo ${LIBRARIES})
 
-if(UNIX)
-    if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
-        add_executable(tri tri.c ${CMAKE_BINARY_DIR}/demos/tri-vert.spv ${CMAKE_BINARY_DIR}/demos/tri-frag.spv)
-    endif()
-else()
-    add_executable(tri WIN32 tri.c ${CMAKE_BINARY_DIR}/demos/tri-vert.spv ${CMAKE_BINARY_DIR}/demos/tri-frag.spv)
-endif()
-if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
-    target_link_libraries(tri ${LIBRARIES})
-endif()
-
 if(NOT WIN32)
     if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
         add_executable(cube cube.c ${CMAKE_BINARY_DIR}/demos/cube-vert.spv ${CMAKE_BINARY_DIR}/demos/cube-frag.spv)
@@ -140,9 +108,29 @@
     endif()
 
     add_executable(cube WIN32 cube.c ${CMAKE_BINARY_DIR}/demos/cube-vert.spv ${CMAKE_BINARY_DIR}/demos/cube-frag.spv)
-    target_link_libraries(cube ${LIBRARIES} )
+    target_link_libraries(cube ${LIBRARIES})
+endif()
+
+if(NOT WIN32)
+    if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
+        add_executable(cubepp cube.cpp ${CMAKE_BINARY_DIR}/demos/cube-vert.spv ${CMAKE_BINARY_DIR}/demos/cube-frag.spv)
+        target_link_libraries(cubepp ${LIBRARIES})
+    endif()
+else()
+    if (CMAKE_CL_64)
+        set (LIB_DIR "Win64")
+    else()
+        set (LIB_DIR "Win32")
+    endif()
+
+    add_executable(cubepp WIN32 cube.cpp ${CMAKE_BINARY_DIR}/demos/cube-vert.spv ${CMAKE_BINARY_DIR}/demos/cube-frag.spv)
+    target_link_libraries(cubepp ${LIBRARIES})
 endif()
 
 if (${CMAKE_SYSTEM_PROCESSOR} STREQUAL ${CMAKE_HOST_SYSTEM_PROCESSOR})
     add_subdirectory(smoke)
 endif()
+
+if(UNIX)
+    install(TARGETS vulkaninfo DESTINATION bin)
+endif()
diff --git a/demos/android/AndroidManifest.xml.tri b/demos/android/cube-with-layers/AndroidManifest.xml
similarity index 75%
rename from demos/android/AndroidManifest.xml.tri
rename to demos/android/cube-with-layers/AndroidManifest.xml
index 00ff122..a78de86 100644
--- a/demos/android/AndroidManifest.xml.tri
+++ b/demos/android/cube-with-layers/AndroidManifest.xml
@@ -1,5 +1,10 @@
 <?xml version="1.0"?>

-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.Tri" android:versionCode="1" android:versionName="1.0">

+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.CubeWithLayers" android:versionCode="1" android:versionName="1.0">

+

+    <!-- Allow this app to read and write files (for use by tracing libraries). -->
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

+    <uses-permission android:name="android.permission.INTERNET"/>
 

     <!-- Allow this app to read and write files (for use by tracing libraries). -->

     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

@@ -16,7 +21,7 @@
              This will take care of integrating with our NDK code. -->

         <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:exported="true">

             <!-- Tell NativeActivity the name of or .so -->

-            <meta-data android:name="android.app.lib_name" android:value="Tri"/>

+            <meta-data android:name="android.app.lib_name" android:value="Cube"/>

             <intent-filter>

                 <action android:name="android.intent.action.MAIN"/>

                 <category android:name="android.intent.category.LAUNCHER"/>

diff --git a/demos/android/cube-with-layers/custom_rules.xml b/demos/android/cube-with-layers/custom_rules.xml
new file mode 100644
index 0000000..ab517bf
--- /dev/null
+++ b/demos/android/cube-with-layers/custom_rules.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="NativeActivity" default="help">
+
+<property name="cubeWithLayersDir" location="../libs-with-layers" />
+<property name="cubeDir" location="../libs" />
+<property name="layersDir" location="../../../build-android/libs" />
+
+<echo>CubeWithLayers: Creating libs-with-layers</echo>
+<mkdir dir="${cubeWithLayersDir}"/>
+
+<echo>CubeWithLayers: Copying libs from demos/android</echo>
+<copy todir="${cubeWithLayersDir}">
+<fileset dir="${cubeDir}"/>
+</copy>
+
+<echo>CubeWithLayers: Copying layers from build-android</echo>
+<copy todir="${cubeWithLayersDir}">
+<fileset dir="${layersDir}"/>
+</copy>
+
+<!-- Point ndk-build at the libs-with-layers common dir -->
+<echo>CubeWithLayers: Overriding native.libs.absolute.dir with ${cubeWithLayersDir}</echo>
+<property name="native.libs.absolute.dir" location="${cubeWithLayersDir}" />
+
+</project>
diff --git a/demos/android/res/values/strings.xml b/demos/android/cube-with-layers/res/values/strings.xml
similarity index 94%
rename from demos/android/res/values/strings.xml
rename to demos/android/cube-with-layers/res/values/strings.xml
index fdac5f9..bdf81e5 100644
--- a/demos/android/res/values/strings.xml
+++ b/demos/android/cube-with-layers/res/values/strings.xml
@@ -19,6 +19,6 @@
 
 <resources>
     <!-- Simple strings. -->
-    <string name="app_name">Demos</string>
+    <string name="app_name">CubeWithLayers</string>
 
 </resources>
diff --git a/demos/android/AndroidManifest.xml.cube b/demos/android/cube/AndroidManifest.xml
similarity index 100%
rename from demos/android/AndroidManifest.xml.cube
rename to demos/android/cube/AndroidManifest.xml
diff --git a/demos/android/cube/custom_rules.xml b/demos/android/cube/custom_rules.xml
new file mode 100644
index 0000000..335c1c3
--- /dev/null
+++ b/demos/android/cube/custom_rules.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="NativeActivity" default="help">
+<!-- Point ndk-build at the libs created in common dir -->
+<echo>cube: Overriding native.libs.absolute.dir with ../libs</echo>
+<property name="native.libs.absolute.dir" location="../libs" />
+</project>
diff --git a/demos/android/res/values/strings.xml b/demos/android/cube/res/values/strings.xml
similarity index 94%
copy from demos/android/res/values/strings.xml
copy to demos/android/cube/res/values/strings.xml
index fdac5f9..7f175a6 100644
--- a/demos/android/res/values/strings.xml
+++ b/demos/android/cube/res/values/strings.xml
@@ -19,6 +19,6 @@
 
 <resources>
     <!-- Simple strings. -->
-    <string name="app_name">Demos</string>
+    <string name="app_name">Cube</string>
 
 </resources>
diff --git a/demos/android/include/tri.frag.h b/demos/android/include/tri.frag.h
deleted file mode 100644
index 9def3a3..0000000
--- a/demos/android/include/tri.frag.h
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <stdint.h>
-
-#if 0
-../tri.frag
-Warning, version 400 is not yet complete; most version-specific features are present, but some are missing.
-
-
-Linked fragment stage:
-
-
-// Module Version 10000
-// Generated by (magic number): 80001
-// Id's are bound by 20
-
-                              Capability Shader
-               1:             ExtInstImport  "GLSL.std.450"
-                              MemoryModel Logical GLSL450
-                              EntryPoint Fragment 4  "main" 9 17
-                              ExecutionMode 4 OriginUpperLeft
-                              Source GLSL 400
-                              SourceExtension  "GL_ARB_separate_shader_objects"
-                              SourceExtension  "GL_ARB_shading_language_420pack"
-                              Name 4  "main"
-                              Name 9  "uFragColor"
-                              Name 13  "tex"
-                              Name 17  "texcoord"
-                              Decorate 9(uFragColor) Location 0
-                              Decorate 13(tex) DescriptorSet 0
-                              Decorate 13(tex) Binding 0
-                              Decorate 17(texcoord) Location 0
-               2:             TypeVoid
-               3:             TypeFunction 2
-               6:             TypeFloat 32
-               7:             TypeVector 6(float) 4
-               8:             TypePointer Output 7(fvec4)
-   9(uFragColor):      8(ptr) Variable Output
-              10:             TypeImage 6(float) 2D sampled format:Unknown
-              11:             TypeSampledImage 10
-              12:             TypePointer UniformConstant 11
-         13(tex):     12(ptr) Variable UniformConstant
-              15:             TypeVector 6(float) 2
-              16:             TypePointer Input 15(fvec2)
-    17(texcoord):     16(ptr) Variable Input
-         4(main):           2 Function None 3
-               5:             Label
-              14:          11 Load 13(tex)
-              18:   15(fvec2) Load 17(texcoord)
-              19:    7(fvec4) ImageSampleImplicitLod 14 18
-                              Store 9(uFragColor) 19
-                              Return
-                              FunctionEnd
-#endif
-
-static const uint32_t tri_frag[157] = {
-    0x07230203, 0x00010000, 0x00080001, 0x00000014,
-    0x00000000, 0x00020011, 0x00000001, 0x0006000b,
-    0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
-    0x00000000, 0x0003000e, 0x00000000, 0x00000001,
-    0x0007000f, 0x00000004, 0x00000004, 0x6e69616d,
-    0x00000000, 0x00000009, 0x00000011, 0x00030010,
-    0x00000004, 0x00000007, 0x00030003, 0x00000002,
-    0x00000190, 0x00090004, 0x415f4c47, 0x735f4252,
-    0x72617065, 0x5f657461, 0x64616873, 0x6f5f7265,
-    0x63656a62, 0x00007374, 0x00090004, 0x415f4c47,
-    0x735f4252, 0x69646168, 0x6c5f676e, 0x75676e61,
-    0x5f656761, 0x70303234, 0x006b6361, 0x00040005,
-    0x00000004, 0x6e69616d, 0x00000000, 0x00050005,
-    0x00000009, 0x61724675, 0x6c6f4367, 0x0000726f,
-    0x00030005, 0x0000000d, 0x00786574, 0x00050005,
-    0x00000011, 0x63786574, 0x64726f6f, 0x00000000,
-    0x00040047, 0x00000009, 0x0000001e, 0x00000000,
-    0x00040047, 0x0000000d, 0x00000022, 0x00000000,
-    0x00040047, 0x0000000d, 0x00000021, 0x00000000,
-    0x00040047, 0x00000011, 0x0000001e, 0x00000000,
-    0x00020013, 0x00000002, 0x00030021, 0x00000003,
-    0x00000002, 0x00030016, 0x00000006, 0x00000020,
-    0x00040017, 0x00000007, 0x00000006, 0x00000004,
-    0x00040020, 0x00000008, 0x00000003, 0x00000007,
-    0x0004003b, 0x00000008, 0x00000009, 0x00000003,
-    0x00090019, 0x0000000a, 0x00000006, 0x00000001,
-    0x00000000, 0x00000000, 0x00000000, 0x00000001,
-    0x00000000, 0x0003001b, 0x0000000b, 0x0000000a,
-    0x00040020, 0x0000000c, 0x00000000, 0x0000000b,
-    0x0004003b, 0x0000000c, 0x0000000d, 0x00000000,
-    0x00040017, 0x0000000f, 0x00000006, 0x00000002,
-    0x00040020, 0x00000010, 0x00000001, 0x0000000f,
-    0x0004003b, 0x00000010, 0x00000011, 0x00000001,
-    0x00050036, 0x00000002, 0x00000004, 0x00000000,
-    0x00000003, 0x000200f8, 0x00000005, 0x0004003d,
-    0x0000000b, 0x0000000e, 0x0000000d, 0x0004003d,
-    0x0000000f, 0x00000012, 0x00000011, 0x00050057,
-    0x00000007, 0x00000013, 0x0000000e, 0x00000012,
-    0x0003003e, 0x00000009, 0x00000013, 0x000100fd,
-    0x00010038,
-};
diff --git a/demos/android/include/tri.vert.h b/demos/android/include/tri.vert.h
deleted file mode 100644
index e9728fd..0000000
--- a/demos/android/include/tri.vert.h
+++ /dev/null
@@ -1,128 +0,0 @@
-#include <stdint.h>
-
-#if 0
-../tri.vert
-Warning, version 400 is not yet complete; most version-specific features are present, but some are missing.
-
-
-Linked vertex stage:
-
-
-// Module Version 10000
-// Generated by (magic number): 80001
-// Id's are bound by 27
-
-                              Capability Shader
-                              Capability ClipDistance
-               1:             ExtInstImport  "GLSL.std.450"
-                              MemoryModel Logical GLSL450
-                              EntryPoint Vertex 4  "main" 9 11 19 23
-                              Source GLSL 400
-                              SourceExtension  "GL_ARB_separate_shader_objects"
-                              SourceExtension  "GL_ARB_shading_language_420pack"
-                              Name 4  "main"
-                              Name 9  "texcoord"
-                              Name 11  "attr"
-                              Name 17  "gl_PerVertex"
-                              MemberName 17(gl_PerVertex) 0  "gl_Position"
-                              MemberName 17(gl_PerVertex) 1  "gl_PointSize"
-                              MemberName 17(gl_PerVertex) 2  "gl_ClipDistance"
-                              Name 19  ""
-                              Name 23  "pos"
-                              Decorate 9(texcoord) Location 0
-                              Decorate 11(attr) Location 1
-                              MemberDecorate 17(gl_PerVertex) 0 BuiltIn Position
-                              MemberDecorate 17(gl_PerVertex) 1 BuiltIn PointSize
-                              MemberDecorate 17(gl_PerVertex) 2 BuiltIn ClipDistance
-                              Decorate 17(gl_PerVertex) Block
-                              Decorate 23(pos) Location 0
-               2:             TypeVoid
-               3:             TypeFunction 2
-               6:             TypeFloat 32
-               7:             TypeVector 6(float) 2
-               8:             TypePointer Output 7(fvec2)
-     9(texcoord):      8(ptr) Variable Output
-              10:             TypePointer Input 7(fvec2)
-        11(attr):     10(ptr) Variable Input
-              13:             TypeVector 6(float) 4
-              14:             TypeInt 32 0
-              15:     14(int) Constant 1
-              16:             TypeArray 6(float) 15
-17(gl_PerVertex):             TypeStruct 13(fvec4) 6(float) 16
-              18:             TypePointer Output 17(gl_PerVertex)
-              19:     18(ptr) Variable Output
-              20:             TypeInt 32 1
-              21:     20(int) Constant 0
-              22:             TypePointer Input 13(fvec4)
-         23(pos):     22(ptr) Variable Input
-              25:             TypePointer Output 13(fvec4)
-         4(main):           2 Function None 3
-               5:             Label
-              12:    7(fvec2) Load 11(attr)
-                              Store 9(texcoord) 12
-              24:   13(fvec4) Load 23(pos)
-              26:     25(ptr) AccessChain 19 21
-                              Store 26 24
-                              Return
-                              FunctionEnd
-#endif
-
-static const uint32_t tri_vert[228] = {
-    0x07230203, 0x00010000, 0x00080001, 0x0000001b,
-    0x00000000, 0x00020011, 0x00000001, 0x00020011,
-    0x00000020, 0x0006000b, 0x00000001, 0x4c534c47,
-    0x6474732e, 0x3035342e, 0x00000000, 0x0003000e,
-    0x00000000, 0x00000001, 0x0009000f, 0x00000000,
-    0x00000004, 0x6e69616d, 0x00000000, 0x00000009,
-    0x0000000b, 0x00000013, 0x00000017, 0x00030003,
-    0x00000002, 0x00000190, 0x00090004, 0x415f4c47,
-    0x735f4252, 0x72617065, 0x5f657461, 0x64616873,
-    0x6f5f7265, 0x63656a62, 0x00007374, 0x00090004,
-    0x415f4c47, 0x735f4252, 0x69646168, 0x6c5f676e,
-    0x75676e61, 0x5f656761, 0x70303234, 0x006b6361,
-    0x00040005, 0x00000004, 0x6e69616d, 0x00000000,
-    0x00050005, 0x00000009, 0x63786574, 0x64726f6f,
-    0x00000000, 0x00040005, 0x0000000b, 0x72747461,
-    0x00000000, 0x00060005, 0x00000011, 0x505f6c67,
-    0x65567265, 0x78657472, 0x00000000, 0x00060006,
-    0x00000011, 0x00000000, 0x505f6c67, 0x7469736f,
-    0x006e6f69, 0x00070006, 0x00000011, 0x00000001,
-    0x505f6c67, 0x746e696f, 0x657a6953, 0x00000000,
-    0x00070006, 0x00000011, 0x00000002, 0x435f6c67,
-    0x4470696c, 0x61747369, 0x0065636e, 0x00030005,
-    0x00000013, 0x00000000, 0x00030005, 0x00000017,
-    0x00736f70, 0x00040047, 0x00000009, 0x0000001e,
-    0x00000000, 0x00040047, 0x0000000b, 0x0000001e,
-    0x00000001, 0x00050048, 0x00000011, 0x00000000,
-    0x0000000b, 0x00000000, 0x00050048, 0x00000011,
-    0x00000001, 0x0000000b, 0x00000001, 0x00050048,
-    0x00000011, 0x00000002, 0x0000000b, 0x00000003,
-    0x00030047, 0x00000011, 0x00000002, 0x00040047,
-    0x00000017, 0x0000001e, 0x00000000, 0x00020013,
-    0x00000002, 0x00030021, 0x00000003, 0x00000002,
-    0x00030016, 0x00000006, 0x00000020, 0x00040017,
-    0x00000007, 0x00000006, 0x00000002, 0x00040020,
-    0x00000008, 0x00000003, 0x00000007, 0x0004003b,
-    0x00000008, 0x00000009, 0x00000003, 0x00040020,
-    0x0000000a, 0x00000001, 0x00000007, 0x0004003b,
-    0x0000000a, 0x0000000b, 0x00000001, 0x00040017,
-    0x0000000d, 0x00000006, 0x00000004, 0x00040015,
-    0x0000000e, 0x00000020, 0x00000000, 0x0004002b,
-    0x0000000e, 0x0000000f, 0x00000001, 0x0004001c,
-    0x00000010, 0x00000006, 0x0000000f, 0x0005001e,
-    0x00000011, 0x0000000d, 0x00000006, 0x00000010,
-    0x00040020, 0x00000012, 0x00000003, 0x00000011,
-    0x0004003b, 0x00000012, 0x00000013, 0x00000003,
-    0x00040015, 0x00000014, 0x00000020, 0x00000001,
-    0x0004002b, 0x00000014, 0x00000015, 0x00000000,
-    0x00040020, 0x00000016, 0x00000001, 0x0000000d,
-    0x0004003b, 0x00000016, 0x00000017, 0x00000001,
-    0x00040020, 0x00000019, 0x00000003, 0x0000000d,
-    0x00050036, 0x00000002, 0x00000004, 0x00000000,
-    0x00000003, 0x000200f8, 0x00000005, 0x0004003d,
-    0x00000007, 0x0000000c, 0x0000000b, 0x0003003e,
-    0x00000009, 0x0000000c, 0x0004003d, 0x0000000d,
-    0x00000018, 0x00000017, 0x00050041, 0x00000019,
-    0x0000001a, 0x00000013, 0x00000015, 0x0003003e,
-    0x0000001a, 0x00000018, 0x000100fd, 0x00010038,
-};
diff --git a/demos/android/jni/Android.mk b/demos/android/jni/Android.mk
index 5042102..3e4169b 100644
--- a/demos/android/jni/Android.mk
+++ b/demos/android/jni/Android.mk
@@ -18,22 +18,10 @@
 DEMO_DIR := $(SRC_DIR)/demos
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := Tri
-LOCAL_SRC_FILES += $(DEMO_DIR)/tri.c \
-                   $(SRC_DIR)/common/vulkan_wrapper.cpp
-LOCAL_C_INCLUDES += $(SRC_DIR)/include \
-                    $(DEMO_DIR)/android/include \
-                    $(SRC_DIR)/libs \
-                    $(SRC_DIR)/common
-LOCAL_CFLAGS += -DVK_USE_PLATFORM_ANDROID_KHR --include=$(SRC_DIR)/common/vulkan_wrapper.h
-LOCAL_WHOLE_STATIC_LIBRARIES += android_native_app_glue
-LOCAL_LDLIBS    := -llog -landroid
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_MODULE := Cube
 LOCAL_SRC_FILES += $(DEMO_DIR)/cube.c \
-                   $(SRC_DIR)/common/vulkan_wrapper.cpp
+                   $(SRC_DIR)/common/vulkan_wrapper.cpp \
+                   $(SRC_DIR)/common/android_util.cpp
 LOCAL_C_INCLUDES += $(SRC_DIR)/include \
                     $(DEMO_DIR)/android/include \
                     $(SRC_DIR)/libs \
diff --git a/demos/android/jni/Application.mk b/demos/android/jni/Application.mk
index 2571d5a..e991843 100644
--- a/demos/android/jni/Application.mk
+++ b/demos/android/jni/Application.mk
@@ -16,7 +16,7 @@
 APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 mips mips64

 APP_PLATFORM := android-23

 APP_STL := gnustl_static

-APP_MODULES := Tri Cube

+APP_MODULES := Cube

 APP_CPPFLAGS += -std=c++11 -fexceptions -Wall -Werror -Wextra -Wno-unused-parameter -DVK_NO_PROTOTYES -DGLM_FORCE_RADIANS

 APP_CFLAGS += -Wall -Werror -Wextra -Wno-unused-parameter -DVK_NO_PROTOTYES -DGLM_FORCE_RADIANS

 NDK_TOOLCHAIN_VERSION := clang

diff --git a/demos/cube.c b/demos/cube.c
index 161771e..f52e1ea 100644
--- a/demos/cube.c
+++ b/demos/cube.c
@@ -20,6 +20,7 @@
 * Author: Ian Elliott <ian@LunarG.com>
 * Author: Jon Ashburn <jon@lunarg.com>
 * Author: Gwan-gyeong Mun <elongbug@gmail.com>
+* Author: Tony Barbour <tony@LunarG.com>
 */
 
 #define _GNU_SOURCE
@@ -51,6 +52,9 @@
 #define APP_SHORT_NAME "cube"
 #define APP_LONG_NAME "The Vulkan Cube Demo Program"
 
+// Allow a maximum of two outstanding presentation operations.
+#define FRAME_LAG 2
+
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
 #if defined(NDEBUG) && defined(__GNUC__)
@@ -276,6 +280,7 @@
 typedef struct {
     VkImage image;
     VkCommandBuffer cmd;
+    VkCommandBuffer graphics_to_present_cmd;
     VkImageView view;
 } SwapchainBuffers;
 
@@ -309,6 +314,7 @@
     bool prepared;
     bool use_staging_buffer;
     bool use_xlib;
+    bool separate_present_queue;
 
     VkInstance inst;
     VkPhysicalDevice gpu;
@@ -317,8 +323,9 @@
     VkQueue present_queue;
     uint32_t graphics_queue_family_index;
     uint32_t present_queue_family_index;
-    VkSemaphore image_acquired_semaphore;
-    VkSemaphore draw_complete_semaphore;
+    VkSemaphore image_acquired_semaphores[FRAME_LAG];
+    VkSemaphore draw_complete_semaphores[FRAME_LAG];
+    VkSemaphore image_ownership_semaphores[FRAME_LAG];
     VkPhysicalDeviceProperties gpu_props;
     VkQueueFamilyProperties *queue_props;
     VkPhysicalDeviceMemoryProperties memory_properties;
@@ -348,8 +355,11 @@
     uint32_t swapchainImageCount;
     VkSwapchainKHR swapchain;
     SwapchainBuffers *buffers;
+    VkFence fences[FRAME_LAG];
+    int frame_index;
 
     VkCommandPool cmd_pool;
+    VkCommandPool present_cmd_pool;
 
     struct {
         VkFormat format;
@@ -404,48 +414,78 @@
     PFN_vkDebugReportMessageEXT DebugReportMessage;
 
     uint32_t current_buffer;
-    uint32_t queue_count;
+    uint32_t queue_family_count;
 };
 
 VKAPI_ATTR VkBool32 VKAPI_CALL
 dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
     uint64_t srcObject, size_t location, int32_t msgCode,
     const char *pLayerPrefix, const char *pMsg, void *pUserData) {
+
+    // clang-format off
     char *message = (char *)malloc(strlen(pMsg) + 100);
 
     assert(message);
 
-    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
-        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
-            pMsg);
+    // We know we're submitting queues without fences, ignore this
+    if (strstr(pMsg, "vkQueueSubmit parameter, VkFence fence, is null pointer"))
+        return false;
+
+    if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+        sprintf(message, "INFORMATION: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
         validation_error = 1;
     } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
-        // We know that we're submitting queues without fences, ignore this
-        // warning
-        if (strstr(pMsg,
-            "vkQueueSubmit parameter, VkFence fence, is null pointer")) {
-            return false;
-        }
-        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
-            pMsg);
+        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+        validation_error = 1;
+    } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+        sprintf(message, "PERFORMANCE WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+        validation_error = 1;
+    } else if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
+        validation_error = 1;
+    } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+        sprintf(message, "DEBUG: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
         validation_error = 1;
     } else {
+        sprintf(message, "INFORMATION: [%s] Code %d : %s", pLayerPrefix, msgCode, pMsg);
         validation_error = 1;
-        return false;
     }
 
 #ifdef _WIN32
+
     in_callback = true;
     struct demo *demo = (struct demo*) pUserData;
     if (!demo->suppress_popups)
         MessageBox(NULL, message, "Alert", MB_OK);
     in_callback = false;
+
+#elif defined(ANDROID)
+
+    if (msgFlags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
+        __android_log_print(ANDROID_LOG_INFO,  APP_SHORT_NAME, "%s", message);
+    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
+        __android_log_print(ANDROID_LOG_WARN,  APP_SHORT_NAME, "%s", message);
+    } else if (msgFlags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
+        __android_log_print(ANDROID_LOG_WARN,  APP_SHORT_NAME, "%s", message);
+    } else if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
+        __android_log_print(ANDROID_LOG_ERROR, APP_SHORT_NAME, "%s", message);
+    } else if (msgFlags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
+        __android_log_print(ANDROID_LOG_DEBUG, APP_SHORT_NAME, "%s", message);
+    } else {
+        __android_log_print(ANDROID_LOG_INFO,  APP_SHORT_NAME, "%s", message);
+    }
+
 #else
+
     printf("%s\n", message);
     fflush(stdout);
+
 #endif
+
     free(message);
 
+    //clang-format on
+
     /*
     * false indicates that layer should not bail-out of an
     * API call that had validation failures. This may mean that the
@@ -520,7 +560,9 @@
                                   VkImageAspectFlags aspectMask,
                                   VkImageLayout old_image_layout,
                                   VkImageLayout new_image_layout,
-                                  VkAccessFlagBits srcAccessMask) {
+                                  VkAccessFlagBits srcAccessMask,
+                                  VkPipelineStageFlags src_stages,
+                                  VkPipelineStageFlags dest_stages) {
     VkResult U_ASSERT_ONLY err;
 
     if (demo->cmd == VK_NULL_HANDLE) {
@@ -554,31 +596,42 @@
         .image = image,
         .subresourceRange = {aspectMask, 0, 1, 0, 1}};
 
-    if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
+    switch (new_image_layout) {
+    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
         /* Make sure anything that was copying from this image has completed */
-        image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-    }
+        image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+        break;
 
-    if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+    case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
         image_memory_barrier.dstAccessMask =
             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-    }
+        break;
 
-    if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
+    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
         image_memory_barrier.dstAccessMask =
             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    }
+        break;
 
-    if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
-        /* Make sure any Copy or CPU writes to image are flushed */
+    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
         image_memory_barrier.dstAccessMask =
             VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
+        break;
+
+    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
+        image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+        break;
+
+    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
+        image_memory_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+        break;
+
+    default:
+        image_memory_barrier.dstAccessMask = 0;
+        break;
     }
 
-    VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier;
 
-    VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-    VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
+    VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier;
 
     vkCmdPipelineBarrier(demo->cmd, src_stages, dest_stages, 0, 0, NULL, 0,
                          NULL, 1, pmemory_barrier);
@@ -611,27 +664,7 @@
 
     err = vkBeginCommandBuffer(cmd_buf, &cmd_buf_info);
     assert(!err);
-
-    // We can use LAYOUT_UNDEFINED as a wildcard here because we don't care what
-    // happens to the previous contents of the image
-    VkImageMemoryBarrier image_memory_barrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-        .srcAccessMask = 0,
-        .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-        .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
-        .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .image = demo->buffers[demo->current_buffer].image,
-        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
-
-    vkCmdPipelineBarrier(cmd_buf, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
-                         NULL, 0, NULL, 1, &image_memory_barrier);
-
     vkCmdBeginRenderPass(cmd_buf, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
-
     vkCmdBindPipeline(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, demo->pipeline);
     vkCmdBindDescriptorSets(cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS,
                             demo->pipeline_layout, 0, 1, &demo->desc_set, 0,
@@ -653,13 +686,69 @@
     vkCmdSetScissor(cmd_buf, 0, 1, &scissor);
     vkCmdDraw(cmd_buf, 12 * 3, 1, 0, 0);
     // Note that ending the renderpass changes the image's layout from
-    // COLOR_ATTACHEMENT_OPTIMAL to PRESENT_SRC_KHR
+    // COLOR_ATTACHMENT_OPTIMAL to PRESENT_SRC_KHR
     vkCmdEndRenderPass(cmd_buf);
 
+    if (demo->separate_present_queue) {
+        // We have to transfer ownership from the graphics queue family to the
+        // present queue family to be able to present.  Note that we don't have
+        // to transfer from present queue family back to graphics queue family at
+        // the start of the next frame because we don't care about the image's
+        // contents at that point.
+        VkImageMemoryBarrier image_ownership_barrier = {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+            .pNext = NULL,
+            .srcAccessMask = 0,
+            .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+            .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+            .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+            .srcQueueFamilyIndex = demo->graphics_queue_family_index,
+            .dstQueueFamilyIndex = demo->present_queue_family_index,
+            .image = demo->buffers[demo->current_buffer].image,
+            .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
+
+        vkCmdPipelineBarrier(cmd_buf,
+                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                             VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0,
+                             0, NULL, 0, NULL, 1, &image_ownership_barrier);
+    }
     err = vkEndCommandBuffer(cmd_buf);
     assert(!err);
 }
 
+void demo_build_image_ownership_cmd(struct demo *demo, int i) {
+    VkResult U_ASSERT_ONLY err;
+
+    const VkCommandBufferBeginInfo cmd_buf_info = {
+        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+        .pNext = NULL,
+        .flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT,
+        .pInheritanceInfo = NULL,
+    };
+    err = vkBeginCommandBuffer(demo->buffers[i].graphics_to_present_cmd,
+                               &cmd_buf_info);
+    assert(!err);
+
+    VkImageMemoryBarrier image_ownership_barrier = {
+        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+        .pNext = NULL,
+        .srcAccessMask = 0,
+        .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        .oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+        .srcQueueFamilyIndex = demo->graphics_queue_family_index,
+        .dstQueueFamilyIndex = demo->present_queue_family_index,
+        .image = demo->buffers[i].image,
+        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
+
+    vkCmdPipelineBarrier(demo->buffers[i].graphics_to_present_cmd,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0,
+                         NULL, 0, NULL, 1, &image_ownership_barrier);
+    err = vkEndCommandBuffer(demo->buffers[i].graphics_to_present_cmd);
+    assert(!err);
+}
+
 void demo_update_data_buffer(struct demo *demo) {
     mat4x4 MVP, Model, VP;
     int matrixSize = sizeof(MVP);
@@ -687,13 +776,21 @@
 static void demo_draw(struct demo *demo) {
     VkResult U_ASSERT_ONLY err;
 
+    // Ensure no more than FRAME_LAG presentations are outstanding
+    vkWaitForFences(demo->device, 1, &demo->fences[demo->frame_index], VK_TRUE, UINT64_MAX);
+    vkResetFences(demo->device, 1, &demo->fences[demo->frame_index]);
+
     // Get the index of the next available swapchain image:
     err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,
-                                      demo->image_acquired_semaphore, (VkFence)0,
+                                      demo->image_acquired_semaphores[demo->frame_index], demo->fences[demo->frame_index],
                                       &demo->current_buffer);
+
     if (err == VK_ERROR_OUT_OF_DATE_KHR) {
         // demo->swapchain is out of date (e.g. the window was resized) and
         // must be recreated:
+        demo->frame_index += 1;
+        demo->frame_index %= FRAME_LAG;
+
         demo_resize(demo);
         demo_draw(demo);
         return;
@@ -703,39 +800,60 @@
     } else {
         assert(!err);
     }
-
     // Wait for the image acquired semaphore to be signaled to ensure
     // that the image won't be rendered to until the presentation
     // engine has fully released ownership to the application, and it is
     // okay to render to the image.
     VkFence nullFence = VK_NULL_HANDLE;
-    VkPipelineStageFlags pipe_stage_flags =
-        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    VkSubmitInfo submit_info = {
-        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-        .pNext = NULL,
-        .waitSemaphoreCount = 1,
-        .pWaitSemaphores = &demo->image_acquired_semaphore,
-        .pWaitDstStageMask = &pipe_stage_flags,
-        .commandBufferCount = 1,
-        .pCommandBuffers = &demo->buffers[demo->current_buffer].cmd,
-        .signalSemaphoreCount = 1,
-        .pSignalSemaphores = &demo->draw_complete_semaphore};
-
+    VkPipelineStageFlags pipe_stage_flags;
+    VkSubmitInfo submit_info;
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.pNext = NULL;
+    submit_info.pWaitDstStageMask = &pipe_stage_flags;
+    pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    submit_info.waitSemaphoreCount = 1;
+    submit_info.pWaitSemaphores = &demo->image_acquired_semaphores[demo->frame_index];
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &demo->buffers[demo->current_buffer].cmd;
+    submit_info.signalSemaphoreCount = 1;
+    submit_info.pSignalSemaphores = &demo->draw_complete_semaphores[demo->frame_index];
     err = vkQueueSubmit(demo->graphics_queue, 1, &submit_info, nullFence);
     assert(!err);
 
+    if (demo->separate_present_queue) {
+        // If we are using separate queues, change image ownership to the
+        // present queue before presenting, waiting for the draw complete
+        // semaphore and signalling the ownership released semaphore when finished
+        pipe_stage_flags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &demo->draw_complete_semaphores[demo->frame_index];
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers =
+            &demo->buffers[demo->current_buffer].graphics_to_present_cmd;
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &demo->image_ownership_semaphores[demo->frame_index];
+        err = vkQueueSubmit(demo->present_queue, 1, &submit_info, nullFence);
+        assert(!err);
+    }
+
+    // If we are using separate queues we have to wait for image ownership,
+    // otherwise wait for draw complete
     VkPresentInfoKHR present = {
         .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
         .pNext = NULL,
         .waitSemaphoreCount = 1,
-        .pWaitSemaphores = &demo->draw_complete_semaphore,
+        .pWaitSemaphores = (demo->separate_present_queue)
+                               ? &demo->image_ownership_semaphores[demo->frame_index]
+                               : &demo->draw_complete_semaphores[demo->frame_index],
         .swapchainCount = 1,
         .pSwapchains = &demo->swapchain,
         .pImageIndices = &demo->current_buffer,
     };
 
     err = demo->fpQueuePresentKHR(demo->present_queue, &present);
+    demo->frame_index += 1;
+    demo->frame_index %= FRAME_LAG;
+
     if (err == VK_ERROR_OUT_OF_DATE_KHR) {
         // demo->swapchain is out of date (e.g. the window was resized) and
         // must be recreated:
@@ -796,21 +914,59 @@
         demo->height = surfCapabilities.currentExtent.height;
     }
 
-    // If mailbox mode is available, use it, as is the lowest-latency non-
-    // tearing mode.  If not, try IMMEDIATE which will usually be available,
-    // and is fastest (though it tears).  If not, fall back to FIFO which is
-    // always available.
+    // The FIFO present mode is guaranteed by the spec to be supported
+    // and to have no tearing.  It's a great default present mode to use.
     VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
-    for (size_t i = 0; i < presentModeCount; i++) {
+    //  There are times when you may wish to use another present mode.  The
+    //  following code shows how to select them, and the comments provide some
+    //  reasons you may wish to use them.
+    //
+    // It should be noted that Vulkan 1.0 doesn't provide a method for
+    // synchronizing rendering with the presentation engine's display.  There
+    // is a method provided for throttling rendering with the display, but
+    // there are some presentation engines for which this method will not work.
+    // If an application doesn't throttle its rendering, and if it renders much
+    // faster than the refresh rate of the display, this can waste power on
+    // mobile devices.  That is because power is being spent rendering images
+    // that may never be seen.
+//#define DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR
+//#define DESIRE_VK_PRESENT_MODE_MAILBOX_KHR
+//#define DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR
+#if defined(DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR)
+    // VK_PRESENT_MODE_IMMEDIATE_KHR is for applications that don't care about
+    // tearing, or have some way of synchronizing their rendering with the
+    // display.
+    for (size_t i = 0; i < presentModeCount; ++i) {
+        if (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) {
+            swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+            break;
+        }
+    }
+#elif defined(DESIRE_VK_PRESENT_MODE_MAILBOX_KHR)
+    // VK_PRESENT_MODE_MAILBOX_KHR may be useful for applications that
+    // generally render a new presentable image every refresh cycle, but are
+    // occasionally early.  In this case, the application wants the new image
+    // to be displayed instead of the previously-queued-for-presentation image
+    // that has not yet been displayed.
+    for (size_t i = 0; i < presentModeCount; ++i) {
         if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
             swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
             break;
         }
-        if ((swapchainPresentMode != VK_PRESENT_MODE_MAILBOX_KHR) &&
-            (presentModes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR)) {
-            swapchainPresentMode = VK_PRESENT_MODE_IMMEDIATE_KHR;
+    }
+#elif defined(DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR)
+    // VK_PRESENT_MODE_FIFO_RELAXED_KHR is for applications that generally
+    // render a new presentable image every refresh cycle, but are occasionally
+    // late.  In this case (perhaps because of stuttering/latency concerns),
+    // the application wants the late image to be immediately displayed, even
+    // though that may mean some tearing.
+    for (size_t i = 0; i < presentModeCount; ++i) {
+        if (presentModes[i] == VK_PRESENT_MODE_MAILBOX_KHR) {
+            swapchainPresentMode = VK_PRESENT_MODE_MAILBOX_KHR;
+            break;
         }
     }
+#endif
 
     // Determine the number of VkImage's to use in the swap chain.
     // Application desires to only acquire 1 image at a time (which is
@@ -855,17 +1011,6 @@
         .clipped = true,
     };
     uint32_t i;
-    uint32_t queueFamilyIndices[2] = {(uint32_t) demo->graphics_queue_family_index, (uint32_t) demo->present_queue_family_index};
-    if (demo->graphics_queue_family_index != demo->present_queue_family_index)
-    {
-        // If the graphics and present queues are from different queue families, we either have to
-        // explicitly transfer ownership of images between the queues, or we have to create the swapchain
-        // with imageSharingMode as VK_SHARING_MODE_CONCURRENT
-        swapchain_ci.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
-        swapchain_ci.queueFamilyIndexCount = 2;
-        swapchain_ci.pQueueFamilyIndices = queueFamilyIndices;
-    }
-
     err = demo->fpCreateSwapchainKHR(demo->device, &swapchain_ci, NULL,
                                      &demo->swapchain);
     assert(!err);
@@ -922,8 +1067,8 @@
         err = vkCreateImageView(demo->device, &color_image_view, NULL,
                                 &demo->buffers[i].view);
         assert(!err);
-    }
 
+    }
 
     if (NULL != presentModes) {
         free(presentModes);
@@ -993,11 +1138,6 @@
         vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0);
     assert(!err);
 
-    demo_set_image_layout(demo, demo->depth.image, VK_IMAGE_ASPECT_DEPTH_BIT,
-                          VK_IMAGE_LAYOUT_UNDEFINED,
-                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                          0);
-
     /* create image view */
     view.image = demo->depth.image;
     err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view);
@@ -1169,11 +1309,6 @@
     }
 
     tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-    demo_set_image_layout(demo, tex_obj->image, VK_IMAGE_ASPECT_COLOR_BIT,
-                          VK_IMAGE_LAYOUT_PREINITIALIZED, tex_obj->imageLayout,
-                          VK_ACCESS_HOST_WRITE_BIT);
-    /* setting the image layout does not reference the actual memory so no need
-     * to add a mem ref */
 }
 
 static void demo_destroy_texture_image(struct demo *demo,
@@ -1202,6 +1337,12 @@
                 VK_IMAGE_USAGE_SAMPLED_BIT,
                 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                     VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+            // Nothing in the pipeline needs to be complete to start, and don't allow fragment
+            // shader to run until layout transition completes
+            demo_set_image_layout(demo, demo->textures[i].image, VK_IMAGE_ASPECT_COLOR_BIT,
+                                  VK_IMAGE_LAYOUT_PREINITIALIZED, demo->textures[i].imageLayout,
+                                  VK_ACCESS_HOST_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
         } else if (props.optimalTilingFeatures &
                    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
             /* Must use staging buffer to copy linear texture to optimized */
@@ -1221,15 +1362,19 @@
 
             demo_set_image_layout(demo, staging_texture.image,
                                   VK_IMAGE_ASPECT_COLOR_BIT,
-                                  staging_texture.imageLayout,
+                                  VK_IMAGE_LAYOUT_PREINITIALIZED,
                                   VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                  0);
+                                  VK_ACCESS_HOST_WRITE_BIT,
+                                  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                  VK_PIPELINE_STAGE_TRANSFER_BIT);
 
             demo_set_image_layout(demo, demo->textures[i].image,
                                   VK_IMAGE_ASPECT_COLOR_BIT,
-                                  demo->textures[i].imageLayout,
+                                  VK_IMAGE_LAYOUT_PREINITIALIZED,
                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                  0);
+                                  VK_ACCESS_HOST_WRITE_BIT,
+                                  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
+                                  VK_PIPELINE_STAGE_TRANSFER_BIT);
 
             VkImageCopy copy_region = {
                 .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
@@ -1248,7 +1393,9 @@
                                   VK_IMAGE_ASPECT_COLOR_BIT,
                                   VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
                                   demo->textures[i].imageLayout,
-                                  0);
+                                  VK_ACCESS_TRANSFER_WRITE_BIT,
+                                  VK_PIPELINE_STAGE_TRANSFER_BIT,
+                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
 
             demo_flush_init_cmd(demo);
 
@@ -1419,6 +1566,14 @@
 }
 
 static void demo_prepare_render_pass(struct demo *demo) {
+    // The initial layout for the color and depth attachments will be LAYOUT_UNDEFINED
+    // because at the start of the renderpass, we don't care about their contents.
+    // At the start of the subpass, the color attachment's layout will be transitioned
+    // to LAYOUT_COLOR_ATTACHMENT_OPTIMAL and the depth stencil attachment's layout
+    // will be transitioned to LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.  At the end of
+    // the renderpass, the color attachment's layout will be transitioned to
+    // LAYOUT_PRESENT_SRC_KHR to be ready to present.  This is all done as part of
+    // the renderpass, no barriers are necessary.
     const VkAttachmentDescription attachments[2] = {
             [0] =
                 {
@@ -1428,7 +1583,7 @@
                  .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
                  .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                  .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                 .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
                  .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
                 },
             [1] =
@@ -1440,7 +1595,7 @@
                  .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
                  .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
                  .initialLayout =
-                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+                     VK_IMAGE_LAYOUT_UNDEFINED,
                  .finalLayout =
                      VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
                 },
@@ -1825,6 +1980,31 @@
         assert(!err);
     }
 
+    if (demo->separate_present_queue) {
+        const VkCommandPoolCreateInfo cmd_pool_info = {
+            .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+            .pNext = NULL,
+            .queueFamilyIndex = demo->present_queue_family_index,
+            .flags = 0,
+        };
+        err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL,
+                                  &demo->present_cmd_pool);
+        assert(!err);
+        const VkCommandBufferAllocateInfo cmd = {
+            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+            .pNext = NULL,
+            .commandPool = demo->present_cmd_pool,
+            .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+            .commandBufferCount = 1,
+        };
+        for (uint32_t i = 0; i < demo->swapchainImageCount; i++) {
+            err = vkAllocateCommandBuffers(
+                demo->device, &cmd, &demo->buffers[i].graphics_to_present_cmd);
+            assert(!err);
+            demo_build_image_ownership_cmd(demo, i);
+        }
+    }
+
     demo_prepare_descriptor_pool(demo);
     demo_prepare_descriptor_set(demo);
 
@@ -1851,6 +2031,17 @@
     demo->prepared = false;
     vkDeviceWaitIdle(demo->device);
 
+    // Wait for fences from present operations
+    for (i = 0; i < FRAME_LAG; i++) {
+        vkWaitForFences(demo->device, 1, &demo->fences[i], VK_TRUE, UINT64_MAX);
+        vkDestroyFence(demo->device, demo->fences[i], NULL);
+        vkDestroySemaphore(demo->device, demo->image_acquired_semaphores[i], NULL);
+        vkDestroySemaphore(demo->device, demo->draw_complete_semaphores[i], NULL);
+        if (demo->separate_present_queue) {
+            vkDestroySemaphore(demo->device, demo->image_ownership_semaphores[i], NULL);
+        }
+    }
+
     for (i = 0; i < demo->swapchainImageCount; i++) {
         vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL);
     }
@@ -1884,12 +2075,12 @@
                              &demo->buffers[i].cmd);
     }
     free(demo->buffers);
-
     free(demo->queue_props);
-
     vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
-    vkDestroySemaphore(demo->device, demo->image_acquired_semaphore, NULL);
-    vkDestroySemaphore(demo->device, demo->draw_complete_semaphore, NULL);
+
+    if (demo->separate_present_queue) {
+        vkDestroyCommandPool(demo->device, demo->present_cmd_pool, NULL);
+    }
     vkDestroyDevice(demo->device, NULL);
     if (demo->validate) {
         demo->DestroyDebugReportCallback(demo->inst, demo->msg_callback, NULL);
@@ -1966,6 +2157,9 @@
                              &demo->buffers[i].cmd);
     }
     vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
+    if (demo->separate_present_queue) {
+        vkDestroyCommandPool(demo->device, demo->present_cmd_pool, NULL);
+    }
     free(demo->buffers);
 
     // Second, re-perform the demo_prepare() function, which will re-create the
@@ -2725,22 +2919,15 @@
     vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props);
 
     /* Call with NULL data to get count */
-    vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count,
-                                             NULL);
-    assert(demo->queue_count >= 1);
+    vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu,
+                                             &demo->queue_family_count, NULL);
+    assert(demo->queue_family_count >= 1);
 
     demo->queue_props = (VkQueueFamilyProperties *)malloc(
-        demo->queue_count * sizeof(VkQueueFamilyProperties));
-    vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count,
-                                             demo->queue_props);
-    // Find a queue that supports gfx
-    uint32_t gfx_queue_idx = 0;
-    for (gfx_queue_idx = 0; gfx_queue_idx < demo->queue_count;
-         gfx_queue_idx++) {
-        if (demo->queue_props[gfx_queue_idx].queueFlags & VK_QUEUE_GRAPHICS_BIT)
-            break;
-    }
-    assert(gfx_queue_idx < demo->queue_count);
+        demo->queue_family_count * sizeof(VkQueueFamilyProperties));
+    vkGetPhysicalDeviceQueueFamilyProperties(
+        demo->gpu, &demo->queue_family_count, demo->queue_props);
+
     // Query fine-grained feature support for this device.
     //  If app has specific feature requirements it should check supported
     //  features based on this query
@@ -2757,18 +2944,19 @@
 static void demo_create_device(struct demo *demo) {
     VkResult U_ASSERT_ONLY err;
     float queue_priorities[1] = {0.0};
-    const VkDeviceQueueCreateInfo queue = {
-        .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
-        .pNext = NULL,
-        .queueFamilyIndex = demo->graphics_queue_family_index,
-        .queueCount = 1,
-        .pQueuePriorities = queue_priorities};
+    VkDeviceQueueCreateInfo queues[2];
+    queues[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+    queues[0].pNext = NULL;
+    queues[0].queueFamilyIndex = demo->graphics_queue_family_index;
+    queues[0].queueCount = 1;
+    queues[0].pQueuePriorities = queue_priorities;
+    queues[0].flags = 0;
 
     VkDeviceCreateInfo device = {
         .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
         .pNext = NULL,
         .queueCreateInfoCount = 1,
-        .pQueueCreateInfos = &queue,
+        .pQueueCreateInfos = queues,
         .enabledLayerCount = 0,
         .ppEnabledLayerNames = NULL,
         .enabledExtensionCount = demo->enabled_extension_count,
@@ -2776,7 +2964,15 @@
         .pEnabledFeatures =
             NULL, // If specific features are required, pass them in here
     };
-
+    if (demo->separate_present_queue) {
+        queues[1].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+        queues[1].pNext = NULL;
+        queues[1].queueFamilyIndex = demo->present_queue_family_index;
+        queues[1].queueCount = 1;
+        queues[1].pQueuePriorities = queue_priorities;
+        queues[1].flags = 0;
+        device.queueCreateInfoCount = 2;
+    }
     err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device);
     assert(!err);
 }
@@ -2844,36 +3040,53 @@
 
     // Iterate over each queue to learn whether it supports presenting:
     VkBool32 *supportsPresent =
-        (VkBool32 *)malloc(demo->queue_count * sizeof(VkBool32));
-    for (i = 0; i < demo->queue_count; i++) {
+        (VkBool32 *)malloc(demo->queue_family_count * sizeof(VkBool32));
+    for (i = 0; i < demo->queue_family_count; i++) {
         demo->fpGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface,
                                                    &supportsPresent[i]);
     }
 
     // Search for a graphics and a present queue in the array of queue
     // families, try to find one that supports both
-    uint32_t graphicsQueueNodeIndex = UINT32_MAX;
-    uint32_t presentQueueNodeIndex = UINT32_MAX;
-    for (i = 0; i < demo->queue_count; i++) {
-        if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0
-                && graphicsQueueNodeIndex == UINT32_MAX) {
-            graphicsQueueNodeIndex = i;
-        }
+    uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
+    uint32_t presentQueueFamilyIndex = UINT32_MAX;
+    for (i = 0; i < demo->queue_family_count; i++) {
+        if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
+            if (graphicsQueueFamilyIndex == UINT32_MAX) {
+                graphicsQueueFamilyIndex = i;
+            }
 
-        if (supportsPresent[i] == VK_TRUE && presentQueueNodeIndex == UINT32_MAX) {
-            presentQueueNodeIndex = i;
+            if (supportsPresent[i] == VK_TRUE) {
+                graphicsQueueFamilyIndex = i;
+                presentQueueFamilyIndex = i;
+                break;
+            }
+        }
+    }
+
+    if (presentQueueFamilyIndex == UINT32_MAX) {
+        // If didn't find a queue that supports both graphics and present, then
+        // find a separate present queue.
+        for (i = 0; i < demo->queue_family_count; ++i) {
+            if (supportsPresent[i] == VK_TRUE) {
+                presentQueueFamilyIndex = i;
+                break;
+            }
         }
     }
 
     // Generate error if could not find both a graphics and a present queue
-    if (graphicsQueueNodeIndex == UINT32_MAX ||
-        presentQueueNodeIndex == UINT32_MAX) {
+    if (graphicsQueueFamilyIndex == UINT32_MAX ||
+        presentQueueFamilyIndex == UINT32_MAX) {
         ERR_EXIT("Could not find both graphics and present queues\n",
                  "Swapchain Initialization Failure");
     }
 
-    demo->graphics_queue_family_index = graphicsQueueNodeIndex;
-    demo->present_queue_family_index = presentQueueNodeIndex;
+    demo->graphics_queue_family_index = graphicsQueueFamilyIndex;
+    demo->present_queue_family_index = presentQueueFamilyIndex;
+    demo->separate_present_queue =
+        (demo->graphics_queue_family_index != demo->present_queue_family_index);
+    free(supportsPresent);
 
     demo_create_device(demo);
 
@@ -2886,7 +3099,7 @@
     vkGetDeviceQueue(demo->device, demo->graphics_queue_family_index, 0,
                      &demo->graphics_queue);
 
-    if (demo->graphics_queue_family_index == demo->present_queue_family_index) {
+    if (!demo->separate_present_queue) {
         demo->present_queue = demo->graphics_queue;
     } else {
         vkGetDeviceQueue(demo->device, demo->present_queue_family_index, 0,
@@ -2924,13 +3137,31 @@
         .pNext = NULL,
         .flags = 0,
     };
-    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
-                            &demo->image_acquired_semaphore);
-    assert(!err);
 
-    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
-                            &demo->draw_complete_semaphore);
-    assert(!err);
+    // Create fences that we can use to throttle if we get too far
+    // ahead of the image presents
+    VkFenceCreateInfo fence_ci = {
+        .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+        .pNext = NULL,
+        .flags = VK_FENCE_CREATE_SIGNALED_BIT
+    };
+    for (uint32_t i = 0; i < FRAME_LAG; i++) {
+        vkCreateFence(demo->device, &fence_ci, NULL, &demo->fences[i]);
+        err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
+                                &demo->image_acquired_semaphores[i]);
+        assert(!err);
+
+        err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
+                                &demo->draw_complete_semaphores[i]);
+        assert(!err);
+
+        if (demo->separate_present_queue) {
+            err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo, NULL,
+                                    &demo->image_ownership_semaphores[i]);
+            assert(!err);
+        }
+    }
+    demo->frame_index = 0;
 
     // Get Memory information and properties
     vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);
@@ -3033,6 +3264,9 @@
             continue;
         }
 
+#if defined(ANDROID)
+        ERR_EXIT("Usage: cube [--validate]\n", "Usage");
+#else
         fprintf(stderr, "Usage:\n  %s [--use_staging] [--validate] [--break] "
 #if defined(VK_USE_PLATFORM_XLIB_KHR)
                         "[--xlib] "
@@ -3041,6 +3275,7 @@
                 APP_SHORT_NAME);
         fflush(stderr);
         exit(1);
+#endif
     }
 
     if (!demo->use_xlib)
@@ -3051,8 +3286,8 @@
     demo->width = 500;
     demo->height = 500;
 
-    demo->spin_angle = 0.01f;
-    demo->spin_increment = 0.01f;
+    demo->spin_angle = 4.0f;
+    demo->spin_increment = 0.2f;
     demo->pause = false;
 
     mat4x4_perspective(demo->projection_matrix, (float)degreesToRadians(45.0f),
@@ -3147,6 +3382,8 @@
 #elif defined(VK_USE_PLATFORM_ANDROID_KHR)
 #include <android/log.h>
 #include <android_native_app_glue.h>
+#include "android_util.h"
+
 static bool initialized = false;
 static bool active = false;
 struct demo demo;
@@ -3172,7 +3409,25 @@
                 if (demo.prepared) {
                     demo_cleanup(&demo);
                 }
-                demo_init(&demo, 0, NULL);
+
+                // Parse Intents into argc, argv
+                // Use the following key to send arguments, i.e.
+                // --es args "--validate"
+                const char key[] = "args";
+                char* appTag = (char*) APP_SHORT_NAME;
+                int argc = 0;
+                char** argv = get_args(app, key, appTag, &argc);
+
+                __android_log_print(ANDROID_LOG_INFO, appTag, "argc = %i", argc);
+                for (int i = 0; i < argc; i++)
+                    __android_log_print(ANDROID_LOG_INFO, appTag, "argv[%i] = %s", i, argv[i]);
+
+                demo_init(&demo, argc, argv);
+
+                // Free the argv malloc'd by get_args
+                for (int i = 0; i < argc; i++)
+                    free(argv[i]);
+
                 demo.window = (void*)app->window;
                 demo_init_vk_swapchain(&demo);
                 demo_prepare(&demo);
diff --git a/demos/cube.cpp b/demos/cube.cpp
new file mode 100644
index 0000000..a0c7c47
--- /dev/null
+++ b/demos/cube.cpp
@@ -0,0 +1,2887 @@
+/*
+* Copyright (c) 2015-2016 The Khronos Group Inc.
+* Copyright (c) 2015-2016 Valve Corporation
+* Copyright (c) 2015-2016 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: Jeremy Hayes <jeremy@lunarg.com>
+*/
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+#include <X11/Xutil.h>
+#endif
+
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <csignal>
+#include <memory>
+
+#define VULKAN_HPP_NO_EXCEPTIONS
+#include <vulkan/vulkan.hpp>
+#include <vulkan/vk_sdk_platform.h>
+
+#include "linmath.h"
+
+#ifndef NDEBUG
+#define VERIFY(x) assert(x)
+#else
+#define VERIFY(x) ((void)(x))
+#endif
+
+#define APP_SHORT_NAME "cube"
+#ifdef _WIN32
+#define APP_NAME_STR_LEN 80
+#endif
+
+// Allow a maximum of two outstanding presentation operations.
+#define FRAME_LAG 2
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+#ifdef _WIN32
+#define ERR_EXIT(err_msg, err_class)                                           \
+    do {                                                                       \
+        if (!suppress_popups)                                                  \
+            MessageBox(nullptr, err_msg, err_class, MB_OK);                    \
+        exit(1);                                                               \
+    } while (0)
+#else
+#define ERR_EXIT(err_msg, err_class)                                           \
+    do {                                                                       \
+        printf(err_msg);                                                       \
+        fflush(stdout);                                                        \
+        exit(1);                                                               \
+    } while (0)
+#endif
+
+struct texture_object {
+    vk::Sampler sampler;
+
+    vk::Image image;
+    vk::ImageLayout imageLayout;
+
+    vk::MemoryAllocateInfo mem_alloc;
+    vk::DeviceMemory mem;
+    vk::ImageView view;
+
+    int32_t tex_width;
+    int32_t tex_height;
+};
+
+static char const *const tex_files[] = {"lunarg.ppm"};
+
+static int validation_error = 0;
+
+struct vkcube_vs_uniform {
+    // Must start with MVP
+    float mvp[4][4];
+    float position[12 * 3][4];
+    float color[12 * 3][4];
+};
+
+struct vktexcube_vs_uniform {
+    // Must start with MVP
+    float mvp[4][4];
+    float position[12 * 3][4];
+    float attr[12 * 3][4];
+};
+
+//--------------------------------------------------------------------------------------
+// Mesh and VertexFormat Data
+//--------------------------------------------------------------------------------------
+// clang-format off
+static const float g_vertex_buffer_data[] = {
+    -1.0f,-1.0f,-1.0f,  // -X side
+    -1.0f,-1.0f, 1.0f,
+    -1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f,-1.0f,
+    -1.0f,-1.0f,-1.0f,
+
+    -1.0f,-1.0f,-1.0f,  // -Z side
+     1.0f, 1.0f,-1.0f,
+     1.0f,-1.0f,-1.0f,
+    -1.0f,-1.0f,-1.0f,
+    -1.0f, 1.0f,-1.0f,
+     1.0f, 1.0f,-1.0f,
+
+    -1.0f,-1.0f,-1.0f,  // -Y side
+     1.0f,-1.0f,-1.0f,
+     1.0f,-1.0f, 1.0f,
+    -1.0f,-1.0f,-1.0f,
+     1.0f,-1.0f, 1.0f,
+    -1.0f,-1.0f, 1.0f,
+
+    -1.0f, 1.0f,-1.0f,  // +Y side
+    -1.0f, 1.0f, 1.0f,
+     1.0f, 1.0f, 1.0f,
+    -1.0f, 1.0f,-1.0f,
+     1.0f, 1.0f, 1.0f,
+     1.0f, 1.0f,-1.0f,
+
+     1.0f, 1.0f,-1.0f,  // +X side
+     1.0f, 1.0f, 1.0f,
+     1.0f,-1.0f, 1.0f,
+     1.0f,-1.0f, 1.0f,
+     1.0f,-1.0f,-1.0f,
+     1.0f, 1.0f,-1.0f,
+
+    -1.0f, 1.0f, 1.0f,  // +Z side
+    -1.0f,-1.0f, 1.0f,
+     1.0f, 1.0f, 1.0f,
+    -1.0f,-1.0f, 1.0f,
+     1.0f,-1.0f, 1.0f,
+     1.0f, 1.0f, 1.0f,
+};
+
+static const float g_uv_buffer_data[] = {
+    0.0f, 1.0f,  // -X side
+    1.0f, 1.0f,
+    1.0f, 0.0f,
+    1.0f, 0.0f,
+    0.0f, 0.0f,
+    0.0f, 1.0f,
+
+    1.0f, 1.0f,  // -Z side
+    0.0f, 0.0f,
+    0.0f, 1.0f,
+    1.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 0.0f,
+
+    1.0f, 0.0f,  // -Y side
+    1.0f, 1.0f,
+    0.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 1.0f,
+    0.0f, 0.0f,
+
+    1.0f, 0.0f,  // +Y side
+    0.0f, 0.0f,
+    0.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 1.0f,
+    1.0f, 1.0f,
+
+    1.0f, 0.0f,  // +X side
+    0.0f, 0.0f,
+    0.0f, 1.0f,
+    0.0f, 1.0f,
+    1.0f, 1.0f,
+    1.0f, 0.0f,
+
+    0.0f, 0.0f,  // +Z side
+    0.0f, 1.0f,
+    1.0f, 0.0f,
+    0.0f, 1.0f,
+    1.0f, 1.0f,
+    1.0f, 0.0f,
+};
+// clang-format on
+
+typedef struct {
+    vk::Image image;
+    vk::CommandBuffer cmd;
+    vk::CommandBuffer graphics_to_present_cmd;
+    vk::ImageView view;
+} SwapchainBuffers;
+
+#ifdef _WIN32
+// MS-Windows event handling function:
+LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+#endif
+
+struct Demo {
+    Demo()
+        :
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+          connection{nullptr},
+          window{nullptr},
+          minsize(POINT{
+              0, 0}), // Use explicit construction to avoid MSVC error C2797.
+#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+          display{nullptr},
+          xlib_window{0}, xlib_wm_delete_window{0}, connection{nullptr},
+          screen{nullptr}, xcb_window{0}, atom_wm_delete_window{nullptr},
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+          display{nullptr},
+          registry{nullptr}, compositor{nullptr}, window{nullptr},
+          shell{nullptr}, shell_surface{nullptr},
+#endif
+          prepared{false},
+          use_staging_buffer{false}, use_xlib{false},
+          graphics_queue_family_index{0}, present_queue_family_index{0},
+          enabled_extension_count{0}, enabled_layer_count{0}, width{0},
+          height{0}, swapchainImageCount{0}, frame_index{0}, spin_angle{0.0f},
+          spin_increment{0.0f}, pause{false}, quit{false}, curFrame{0},
+          frameCount{0}, validate{false}, use_break{false},
+          suppress_popups{false}, current_buffer{0}, queue_family_count{0} {
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        memset(name, '\0', APP_NAME_STR_LEN);
+#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+#endif
+        memset(fencesInited, 0, sizeof(bool) * FRAME_LAG);
+        memset(projection_matrix, 0, sizeof(projection_matrix));
+        memset(view_matrix, 0, sizeof(view_matrix));
+        memset(model_matrix, 0, sizeof(model_matrix));
+    }
+
+    void build_image_ownership_cmd(uint32_t const &i) {
+        auto const cmd_buf_info = vk::CommandBufferBeginInfo().setFlags(
+            vk::CommandBufferUsageFlagBits::eSimultaneousUse);
+        auto result = buffers[i].graphics_to_present_cmd.begin(&cmd_buf_info);
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto const image_ownership_barrier =
+            vk::ImageMemoryBarrier()
+                .setSrcAccessMask(vk::AccessFlags())
+                .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
+                .setOldLayout(vk::ImageLayout::ePresentSrcKHR)
+                .setNewLayout(vk::ImageLayout::ePresentSrcKHR)
+                .setSrcQueueFamilyIndex(graphics_queue_family_index)
+                .setDstQueueFamilyIndex(present_queue_family_index)
+                .setImage(buffers[i].image)
+                .setSubresourceRange(vk::ImageSubresourceRange(
+                    vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
+
+        buffers[i].graphics_to_present_cmd.pipelineBarrier(
+            vk::PipelineStageFlagBits::eColorAttachmentOutput,
+            vk::PipelineStageFlagBits::eColorAttachmentOutput,
+            vk::DependencyFlagBits(), 0, nullptr, 0, nullptr, 1,
+            &image_ownership_barrier);
+
+        result = buffers[i].graphics_to_present_cmd.end();
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    vk::Bool32 check_layers(uint32_t check_count,
+                            char const *const *const check_names,
+                            uint32_t layer_count, vk::LayerProperties *layers) {
+        for (uint32_t i = 0; i < check_count; i++) {
+            vk::Bool32 found = VK_FALSE;
+            for (uint32_t j = 0; j < layer_count; j++) {
+                if (!strcmp(check_names[i], layers[j].layerName)) {
+                    found = VK_TRUE;
+                    break;
+                }
+            }
+            if (!found) {
+                fprintf(stderr, "Cannot find layer: %s\n", check_names[i]);
+                return 0;
+            }
+        }
+        return VK_TRUE;
+    }
+
+    void cleanup() {
+        prepared = false;
+        device.waitIdle();
+
+        // Wait for fences from present operations
+        for (uint32_t i = 0; i < FRAME_LAG; i++) {
+            if (fencesInited[i]) {
+                device.waitForFences(1, &fences[i], VK_TRUE, UINT64_MAX);
+            }
+            device.destroyFence(fences[i], nullptr);
+            device.destroySemaphore(image_acquired_semaphores[i], nullptr);
+            device.destroySemaphore(draw_complete_semaphores[i], nullptr);
+            if (separate_present_queue) {
+                device.destroySemaphore(image_ownership_semaphores[i], nullptr);
+            }
+        }
+
+        for (uint32_t i = 0; i < swapchainImageCount; i++) {
+            device.destroyFramebuffer(framebuffers[i], nullptr);
+        }
+        device.destroyDescriptorPool(desc_pool, nullptr);
+
+        device.destroyPipeline(pipeline, nullptr);
+        device.destroyPipelineCache(pipelineCache, nullptr);
+        device.destroyRenderPass(render_pass, nullptr);
+        device.destroyPipelineLayout(pipeline_layout, nullptr);
+        device.destroyDescriptorSetLayout(desc_layout, nullptr);
+
+        for (uint32_t i = 0; i < texture_count; i++) {
+            device.destroyImageView(textures[i].view, nullptr);
+            device.destroyImage(textures[i].image, nullptr);
+            device.freeMemory(textures[i].mem, nullptr);
+            device.destroySampler(textures[i].sampler, nullptr);
+        }
+        device.destroySwapchainKHR(swapchain, nullptr);
+
+        device.destroyImageView(depth.view, nullptr);
+        device.destroyImage(depth.image, nullptr);
+        device.freeMemory(depth.mem, nullptr);
+
+        device.destroyBuffer(uniform_data.buf, nullptr);
+        device.freeMemory(uniform_data.mem, nullptr);
+
+        for (uint32_t i = 0; i < swapchainImageCount; i++) {
+            device.destroyImageView(buffers[i].view, nullptr);
+            device.freeCommandBuffers(cmd_pool, 1, &buffers[i].cmd);
+        }
+
+        device.destroyCommandPool(cmd_pool, nullptr);
+
+        if (separate_present_queue) {
+            device.destroyCommandPool(present_cmd_pool, nullptr);
+        }
+
+        device.destroy(nullptr);
+        inst.destroySurfaceKHR(surface, nullptr);
+        inst.destroy(nullptr);
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+        if (use_xlib) {
+            XDestroyWindow(display, xlib_window);
+            XCloseDisplay(display);
+        } else {
+            xcb_destroy_window(connection, xcb_window);
+            xcb_disconnect(connection);
+        }
+        free(atom_wm_delete_window);
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        wl_shell_surface_destroy(shell_surface);
+        wl_surface_destroy(window);
+        wl_shell_destroy(shell);
+        wl_compositor_destroy(compositor);
+        wl_registry_destroy(registry);
+        wl_display_disconnect(display);
+#endif
+    }
+
+    void create_device() {
+        float const priorities[1] = {0.0};
+
+        vk::DeviceQueueCreateInfo queues[2];
+        queues[0].setQueueFamilyIndex(graphics_queue_family_index);
+        queues[0].setQueueCount(1);
+        queues[0].setPQueuePriorities(priorities);
+
+        auto deviceInfo = vk::DeviceCreateInfo()
+                              .setQueueCreateInfoCount(1)
+                              .setPQueueCreateInfos(queues)
+                              .setEnabledLayerCount(0)
+                              .setPpEnabledLayerNames(nullptr)
+                              .setEnabledExtensionCount(enabled_extension_count)
+                              .setPpEnabledExtensionNames(
+                                  (const char *const *)extension_names)
+                              .setPEnabledFeatures(nullptr);
+
+        if (separate_present_queue) {
+            queues[1].setQueueFamilyIndex(present_queue_family_index);
+            queues[1].setQueueCount(1);
+            queues[1].setPQueuePriorities(priorities);
+            deviceInfo.setQueueCreateInfoCount(2);
+        }
+
+        auto result = gpu.createDevice(&deviceInfo, nullptr, &device);
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    void destroy_texture_image(texture_object *tex_objs) {
+        // clean up staging resources
+        device.freeMemory(tex_objs->mem, nullptr);
+        device.destroyImage(tex_objs->image, nullptr);
+    }
+
+    void draw() {
+        if (fencesInited[frame_index]) {
+            // Ensure no more than FRAME_LAG presentations are outstanding
+            device.waitForFences(1, &fences[frame_index], VK_TRUE, UINT64_MAX);
+            device.resetFences(1, &fences[frame_index]);
+        }
+
+        // Get the index of the next available swapchain image:
+        auto result = device.acquireNextImageKHR(
+            swapchain, UINT64_MAX, image_acquired_semaphores[frame_index],
+            fences[frame_index], &current_buffer);
+        fencesInited[frame_index] = true;
+        if (result == vk::Result::eErrorOutOfDateKHR) {
+            // swapchain is out of date (e.g. the window was resized) and
+            // must be recreated:
+            frame_index += 1;
+            frame_index %= FRAME_LAG;
+
+            resize();
+            draw();
+            return;
+        } else if (result == vk::Result::eSuboptimalKHR) {
+            // swapchain is not as optimal as it could be, but the platform's
+            // presentation engine will still present the image correctly.
+        } else {
+            VERIFY(result == vk::Result::eSuccess);
+        }
+
+        // Wait for the image acquired semaphore to be signaled to ensure
+        // that the image won't be rendered to until the presentation
+        // engine has fully released ownership to the application, and it is
+        // okay to render to the image.
+        vk::PipelineStageFlags const pipe_stage_flags =
+            vk::PipelineStageFlagBits::eColorAttachmentOutput;
+        auto const submit_info =
+            vk::SubmitInfo()
+                .setPWaitDstStageMask(&pipe_stage_flags)
+                .setWaitSemaphoreCount(1)
+                .setPWaitSemaphores(&image_acquired_semaphores[frame_index])
+                .setCommandBufferCount(1)
+                .setPCommandBuffers(&buffers[current_buffer].cmd)
+                .setSignalSemaphoreCount(1)
+                .setPSignalSemaphores(&draw_complete_semaphores[frame_index]);
+
+        result = graphics_queue.submit(1, &submit_info, vk::Fence());
+        VERIFY(result == vk::Result::eSuccess);
+
+        if (separate_present_queue) {
+            // If we are using separate queues, change image ownership to the
+            // present queue before presenting, waiting for the draw complete
+            // semaphore and signalling the ownership released semaphore when
+            // finished
+            auto const submit_info =
+                vk::SubmitInfo()
+                    .setPWaitDstStageMask(&pipe_stage_flags)
+                    .setWaitSemaphoreCount(1)
+                    .setPWaitSemaphores(&draw_complete_semaphores[frame_index])
+                    .setCommandBufferCount(1)
+                    .setPCommandBuffers(
+                        &buffers[current_buffer].graphics_to_present_cmd)
+                    .setSignalSemaphoreCount(1)
+                    .setPSignalSemaphores(
+                        &image_ownership_semaphores[frame_index]);
+
+            result = present_queue.submit(1, &submit_info, vk::Fence());
+            VERIFY(result == vk::Result::eSuccess);
+        }
+
+        // If we are using separate queues we have to wait for image ownership,
+        // otherwise wait for draw complete
+        auto const presentInfo =
+            vk::PresentInfoKHR()
+                .setWaitSemaphoreCount(1)
+                .setPWaitSemaphores(
+                    separate_present_queue
+                        ? &image_ownership_semaphores[frame_index]
+                        : &draw_complete_semaphores[frame_index])
+                .setSwapchainCount(1)
+                .setPSwapchains(&swapchain)
+                .setPImageIndices(&current_buffer);
+
+        result = present_queue.presentKHR(&presentInfo);
+        frame_index += 1;
+        frame_index %= FRAME_LAG;
+        if (result == vk::Result::eErrorOutOfDateKHR) {
+            // swapchain is out of date (e.g. the window was resized) and
+            // must be recreated:
+            resize();
+        } else if (result == vk::Result::eSuboptimalKHR) {
+            // swapchain is not as optimal as it could be, but the platform's
+            // presentation engine will still present the image correctly.
+        } else {
+            VERIFY(result == vk::Result::eSuccess);
+        }
+    }
+
+    void draw_build_cmd(vk::CommandBuffer commandBuffer) {
+        auto const commandInfo = vk::CommandBufferBeginInfo().setFlags(
+            vk::CommandBufferUsageFlagBits::eSimultaneousUse);
+
+        vk::ClearValue const clearValues[2] = {
+            vk::ClearColorValue(std::array<float, 4>({0.2f, 0.2f, 0.2f, 0.2f})),
+            vk::ClearDepthStencilValue(1.0f, 0u)};
+
+        auto const passInfo =
+            vk::RenderPassBeginInfo()
+                .setRenderPass(render_pass)
+                .setFramebuffer(framebuffers[current_buffer])
+                .setRenderArea(
+                    vk::Rect2D(vk::Offset2D(0, 0),
+                               vk::Extent2D((uint32_t)width, (uint32_t)height)))
+                .setClearValueCount(2)
+                .setPClearValues(clearValues);
+
+        auto result = commandBuffer.begin(&commandInfo);
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto const image_memory_barrier =
+            vk::ImageMemoryBarrier()
+                .setSrcAccessMask(vk::AccessFlagBits::eMemoryRead)
+                .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
+                .setOldLayout(vk::ImageLayout::ePresentSrcKHR)
+                .setNewLayout(vk::ImageLayout::eColorAttachmentOptimal)
+                .setSrcQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
+                .setDstQueueFamilyIndex(VK_QUEUE_FAMILY_IGNORED)
+                .setImage(buffers[current_buffer].image)
+                .setSubresourceRange(vk::ImageSubresourceRange(
+                    vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
+
+        commandBuffer.pipelineBarrier(
+            vk::PipelineStageFlagBits::eColorAttachmentOutput,
+            vk::PipelineStageFlagBits::eColorAttachmentOutput,
+            vk::DependencyFlagBits(), 0, nullptr, 0, nullptr, 1,
+            &image_memory_barrier);
+
+        commandBuffer.beginRenderPass(&passInfo, vk::SubpassContents::eInline);
+
+        commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline);
+        commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics,
+                                         pipeline_layout, 0, 1, &desc_set, 0,
+                                         nullptr);
+
+        auto const viewport = vk::Viewport()
+                                  .setWidth((float)width)
+                                  .setHeight((float)height)
+                                  .setMinDepth((float)0.0f)
+                                  .setMaxDepth((float)1.0f);
+        commandBuffer.setViewport(0, 1, &viewport);
+
+        vk::Rect2D const scissor(vk::Offset2D(0, 0),
+                                 vk::Extent2D(width, height));
+        commandBuffer.setScissor(0, 1, &scissor);
+        commandBuffer.draw(12 * 3, 1, 0, 0);
+        // Note that ending the renderpass changes the image's layout from
+        // COLOR_ATTACHMENT_OPTIMAL to PRESENT_SRC_KHR
+        commandBuffer.endRenderPass();
+
+        if (separate_present_queue) {
+            // We have to transfer ownership from the graphics queue family to
+            // the
+            // present queue family to be able to present.  Note that we don't
+            // have
+            // to transfer from present queue family back to graphics queue
+            // family at
+            // the start of the next frame because we don't care about the
+            // image's
+            // contents at that point.
+            auto const image_ownership_barrier =
+                vk::ImageMemoryBarrier()
+                    .setSrcAccessMask(vk::AccessFlags())
+                    .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
+                    .setOldLayout(vk::ImageLayout::ePresentSrcKHR)
+                    .setNewLayout(vk::ImageLayout::ePresentSrcKHR)
+                    .setSrcQueueFamilyIndex(graphics_queue_family_index)
+                    .setDstQueueFamilyIndex(present_queue_family_index)
+                    .setImage(buffers[current_buffer].image)
+                    .setSubresourceRange(vk::ImageSubresourceRange(
+                        vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
+
+            commandBuffer.pipelineBarrier(
+                vk::PipelineStageFlagBits::eColorAttachmentOutput,
+                vk::PipelineStageFlagBits::eColorAttachmentOutput,
+                vk::DependencyFlagBits(), 0, nullptr, 0, nullptr, 1,
+                &image_ownership_barrier);
+        }
+
+        result = commandBuffer.end();
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    void flush_init_cmd() {
+        // TODO: hmm.
+        // This function could get called twice if the texture uses a staging
+        // buffer
+        // In that case the second call should be ignored
+        if (!cmd) {
+            return;
+        }
+
+        auto result = cmd.end();
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto const fenceInfo =
+            vk::FenceCreateInfo().setFlags(vk::FenceCreateFlagBits(0));
+        vk::Fence fence;
+        device.createFence(&fenceInfo, nullptr, &fence);
+
+        vk::CommandBuffer const commandBuffers[] = {cmd};
+        auto const submitInfo =
+            vk::SubmitInfo().setCommandBufferCount(1).setPCommandBuffers(
+                commandBuffers);
+
+        result = graphics_queue.submit(1, &submitInfo, fence);
+        VERIFY(result == vk::Result::eSuccess);
+
+        result = device.waitForFences(1, &fence, VK_TRUE, UINT64_MAX);
+        VERIFY(result == vk::Result::eSuccess);
+
+        device.freeCommandBuffers(cmd_pool, 1, commandBuffers);
+        device.destroyFence(fence, nullptr);
+
+        cmd = vk::CommandBuffer();
+    }
+
+    void init(int argc, char **argv) {
+        vec3 eye = {0.0f, 3.0f, 5.0f};
+        vec3 origin = {0, 0, 0};
+        vec3 up = {0.0f, 1.0f, 0.0};
+
+        frameCount = UINT32_MAX;
+        use_xlib = false;
+
+        for (int i = 1; i < argc; i++) {
+            if (strcmp(argv[i], "--use_staging") == 0) {
+                use_staging_buffer = true;
+                continue;
+            }
+            if (strcmp(argv[i], "--break") == 0) {
+                use_break = true;
+                continue;
+            }
+            if (strcmp(argv[i], "--validate") == 0) {
+                validate = true;
+                continue;
+            }
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+            if (strcmp(argv[i], "--xlib") == 0) {
+                use_xlib = true;
+                continue;
+            }
+#endif
+            if (strcmp(argv[i], "--c") == 0 && frameCount == UINT32_MAX &&
+                i < argc - 1 && sscanf(argv[i + 1], "%d", &frameCount) == 1) {
+                i++;
+                continue;
+            }
+            if (strcmp(argv[i], "--suppress_popups") == 0) {
+                suppress_popups = true;
+                continue;
+            }
+
+            fprintf(stderr,
+                    "Usage:\n  %s [--use_staging] [--validate] [--break] "
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+                    "[--xlib] "
+#endif
+                    "[--c <framecount>] [--suppress_popups]\n",
+                    APP_SHORT_NAME);
+            fflush(stderr);
+            exit(1);
+        }
+
+        if (!use_xlib) {
+            init_connection();
+        }
+
+        init_vk();
+
+        width = 500;
+        height = 500;
+
+        spin_angle = 4.0f;
+        spin_increment = 0.2f;
+        pause = false;
+
+        mat4x4_perspective(projection_matrix, (float)degreesToRadians(45.0f),
+                           1.0f, 0.1f, 100.0f);
+        mat4x4_look_at(view_matrix, eye, origin, up);
+        mat4x4_identity(model_matrix);
+
+        projection_matrix[1][1] *=
+            -1; // Flip projection matrix from GL to Vulkan orientation.
+    }
+
+    void init_connection() {
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+        const xcb_setup_t *setup;
+        xcb_screen_iterator_t iter;
+        int scr;
+
+        connection = xcb_connect(nullptr, &scr);
+        if (xcb_connection_has_error(connection) > 0) {
+            printf("Cannot find a compatible Vulkan installable client driver "
+                   "(ICD).\nExiting ...\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        setup = xcb_get_setup(connection);
+        iter = xcb_setup_roots_iterator(setup);
+        while (scr-- > 0)
+            xcb_screen_next(&iter);
+
+        screen = iter.data;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+        display = wl_display_connect(nullptr);
+
+        if (display == nullptr) {
+            printf("Cannot find a compatible Vulkan installable client driver "
+                   "(ICD).\nExiting ...\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        registry = wl_display_get_registry(display);
+        wl_registry_add_listener(registry, &registry_listener, this);
+        wl_display_dispatch(display);
+#endif
+    }
+
+    void init_vk() {
+        uint32_t instance_extension_count = 0;
+        uint32_t instance_layer_count = 0;
+        uint32_t validation_layer_count = 0;
+        char const *const *instance_validation_layers = nullptr;
+        enabled_extension_count = 0;
+        enabled_layer_count = 0;
+
+        char const *const instance_validation_layers_alt1[] = {
+            "VK_LAYER_LUNARG_standard_validation"};
+
+        char const *const instance_validation_layers_alt2[] = {
+            "VK_LAYER_GOOGLE_threading",
+            "VK_LAYER_LUNARG_parameter_validation",
+            "VK_LAYER_LUNARG_object_tracker",
+            "VK_LAYER_LUNARG_image",
+            "VK_LAYER_LUNARG_core_validation",
+            "VK_LAYER_LUNARG_swapchain",
+            "VK_LAYER_GOOGLE_unique_objects"};
+
+        // Look for validation layers
+        vk::Bool32 validation_found = VK_FALSE;
+        if (validate) {
+            auto result = vk::enumerateInstanceLayerProperties(
+                &instance_layer_count, nullptr);
+            VERIFY(result == vk::Result::eSuccess);
+
+            instance_validation_layers = instance_validation_layers_alt1;
+            if (instance_layer_count > 0) {
+                std::unique_ptr<vk::LayerProperties[]> instance_layers(
+                    new vk::LayerProperties[instance_layer_count]);
+                result = vk::enumerateInstanceLayerProperties(
+                    &instance_layer_count, instance_layers.get());
+                VERIFY(result == vk::Result::eSuccess);
+
+                validation_found =
+                    check_layers(ARRAY_SIZE(instance_validation_layers_alt1),
+                                 instance_validation_layers,
+                                 instance_layer_count, instance_layers.get());
+                if (validation_found) {
+                    enabled_layer_count =
+                        ARRAY_SIZE(instance_validation_layers_alt1);
+                    enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
+                    validation_layer_count = 1;
+                } else {
+                    // use alternative set of validation layers
+                    instance_validation_layers =
+                        instance_validation_layers_alt2;
+                    enabled_layer_count =
+                        ARRAY_SIZE(instance_validation_layers_alt2);
+                    validation_found = check_layers(
+                        ARRAY_SIZE(instance_validation_layers_alt2),
+                        instance_validation_layers, instance_layer_count,
+                        instance_layers.get());
+                    validation_layer_count =
+                        ARRAY_SIZE(instance_validation_layers_alt2);
+                    for (uint32_t i = 0; i < validation_layer_count; i++) {
+                        enabled_layers[i] = instance_validation_layers[i];
+                    }
+                }
+            }
+
+            if (!validation_found) {
+                ERR_EXIT("vkEnumerateInstanceLayerProperties failed to find "
+                         "required validation layer.\n\n"
+                         "Please look at the Getting Started guide for "
+                         "additional information.\n",
+                         "vkCreateInstance Failure");
+            }
+        }
+
+        /* Look for instance extensions */
+        vk::Bool32 surfaceExtFound = VK_FALSE;
+        vk::Bool32 platformSurfaceExtFound = VK_FALSE;
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+        vk::Bool32 xlibSurfaceExtFound = VK_FALSE;
+#endif
+        memset(extension_names, 0, sizeof(extension_names));
+
+        auto result = vk::enumerateInstanceExtensionProperties(
+            nullptr, &instance_extension_count, nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+
+        if (instance_extension_count > 0) {
+            std::unique_ptr<vk::ExtensionProperties[]> instance_extensions(
+                new vk::ExtensionProperties[instance_extension_count]);
+            result = vk::enumerateInstanceExtensionProperties(
+                nullptr, &instance_extension_count, instance_extensions.get());
+            VERIFY(result == vk::Result::eSuccess);
+
+            for (uint32_t i = 0; i < instance_extension_count; i++) {
+                if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME,
+                            instance_extensions[i].extensionName)) {
+                    surfaceExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_SURFACE_EXTENSION_NAME;
+                }
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+                if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
+                            instance_extensions[i].extensionName)) {
+                    platformSurfaceExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
+                }
+#endif
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+                if (!strcmp(VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
+                            instance_extensions[i].extensionName)) {
+                    platformSurfaceExtFound = 1;
+                    xlibSurfaceExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
+                }
+#endif
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+                if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME,
+                            instance_extensions[i].extensionName)) {
+                    platformSurfaceExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_XCB_SURFACE_EXTENSION_NAME;
+                }
+#endif
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+                if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
+                            instance_extensions[i].extensionName)) {
+                    platformSurfaceExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
+                }
+#endif
+                assert(enabled_extension_count < 64);
+            }
+        }
+
+        if (!surfaceExtFound) {
+            ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                     "the " VK_KHR_SURFACE_EXTENSION_NAME " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+        }
+
+        if (!platformSurfaceExtFound) {
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+            ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                     "the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME
+                     " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+            ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                     "the " VK_KHR_XCB_SURFACE_EXTENSION_NAME " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+            ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                     "the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+                     " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+#endif
+        }
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+        if (use_xlib && !xlibSurfaceExtFound) {
+            ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
+                     "the " VK_KHR_XLIB_SURFACE_EXTENSION_NAME " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+        }
+#endif
+
+        auto const app = vk::ApplicationInfo()
+                             .setPApplicationName(APP_SHORT_NAME)
+                             .setApplicationVersion(0)
+                             .setPEngineName(APP_SHORT_NAME)
+                             .setEngineVersion(0)
+                             .setApiVersion(VK_API_VERSION_1_0);
+        auto const inst_info =
+            vk::InstanceCreateInfo()
+                .setPApplicationInfo(&app)
+                .setEnabledLayerCount(enabled_layer_count)
+                .setPpEnabledLayerNames(instance_validation_layers)
+                .setEnabledExtensionCount(enabled_extension_count)
+                .setPpEnabledExtensionNames(extension_names);
+
+        result = vk::createInstance(&inst_info, nullptr, &inst);
+        if (result == vk::Result::eErrorIncompatibleDriver) {
+            ERR_EXIT("Cannot find a compatible Vulkan installable client "
+                     "driver (ICD).\n\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+        } else if (result == vk::Result::eErrorExtensionNotPresent) {
+            ERR_EXIT("Cannot find a specified extension library.\n"
+                     "Make sure your layers path is set appropriately.\n",
+                     "vkCreateInstance Failure");
+        } else if (result != vk::Result::eSuccess) {
+            ERR_EXIT("vkCreateInstance failed.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+        }
+
+        /* Make initial call to query gpu_count, then second call for gpu info*/
+        uint32_t gpu_count;
+        result = inst.enumeratePhysicalDevices(&gpu_count, nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+        assert(gpu_count > 0);
+
+        if (gpu_count > 0) {
+            std::unique_ptr<vk::PhysicalDevice[]> physical_devices(
+                new vk::PhysicalDevice[gpu_count]);
+            result = inst.enumeratePhysicalDevices(&gpu_count,
+                                                   physical_devices.get());
+            VERIFY(result == vk::Result::eSuccess);
+            /* For cube demo we just grab the first physical device */
+            gpu = physical_devices[0];
+        } else {
+            ERR_EXIT("vkEnumeratePhysicalDevices reported zero accessible "
+                     "devices.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkEnumeratePhysicalDevices Failure");
+        }
+
+        /* Look for device extensions */
+        uint32_t device_extension_count = 0;
+        vk::Bool32 swapchainExtFound = VK_FALSE;
+        enabled_extension_count = 0;
+        memset(extension_names, 0, sizeof(extension_names));
+
+        result = gpu.enumerateDeviceExtensionProperties(
+            nullptr, &device_extension_count, nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+
+        if (device_extension_count > 0) {
+            std::unique_ptr<vk::ExtensionProperties[]> device_extensions(
+                new vk::ExtensionProperties[device_extension_count]);
+            result = gpu.enumerateDeviceExtensionProperties(
+                nullptr, &device_extension_count, device_extensions.get());
+            VERIFY(result == vk::Result::eSuccess);
+
+            for (uint32_t i = 0; i < device_extension_count; i++) {
+                if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME,
+                            device_extensions[i].extensionName)) {
+                    swapchainExtFound = 1;
+                    extension_names[enabled_extension_count++] =
+                        VK_KHR_SWAPCHAIN_EXTENSION_NAME;
+                }
+                assert(enabled_extension_count < 64);
+            }
+        }
+
+        if (!swapchainExtFound) {
+            ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find "
+                     "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME " extension.\n\n"
+                     "Do you have a compatible Vulkan installable client "
+                     "driver (ICD) installed?\n"
+                     "Please look at the Getting Started guide for additional "
+                     "information.\n",
+                     "vkCreateInstance Failure");
+        }
+
+        gpu.getProperties(&gpu_props);
+
+        /* Call with nullptr data to get count */
+        gpu.getQueueFamilyProperties(&queue_family_count, nullptr);
+        assert(queue_family_count >= 1);
+
+        queue_props.reset(new vk::QueueFamilyProperties[queue_family_count]);
+        gpu.getQueueFamilyProperties(&queue_family_count, queue_props.get());
+
+        // Query fine-grained feature support for this device.
+        //  If app has specific feature requirements it should check supported
+        //  features based on this query
+        vk::PhysicalDeviceFeatures physDevFeatures;
+        gpu.getFeatures(&physDevFeatures);
+    }
+
+    void init_vk_swapchain() {
+// Create a WSI surface for the window:
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+        {
+            auto const createInfo = vk::Win32SurfaceCreateInfoKHR()
+                                        .setHinstance(connection)
+                                        .setHwnd(window);
+
+            auto result =
+                inst.createWin32SurfaceKHR(&createInfo, nullptr, &surface);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR) && !defined(VK_USE_PLATFORM_XCB_KHR)
+        {
+            auto const createInfo = vk::WaylandSurfaceCreateInfoKHR()
+                                        .setDisplay(display)
+                                        .setSurface(window);
+
+            auto result =
+                inst.createWaylandSurfaceKHR(&createInfo, nullptr, &surface);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+#endif
+        if (use_xlib) {
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+            auto const createInfo =
+                vk::XlibSurfaceCreateInfoKHR().setDpy(display).setWindow(
+                    xlib_window);
+
+            auto result =
+                inst.createXlibSurfaceKHR(&createInfo, nullptr, &surface);
+            VERIFY(result == vk::Result::eSuccess);
+#endif
+        } else {
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+            auto const createInfo = vk::XcbSurfaceCreateInfoKHR()
+                                        .setConnection(connection)
+                                        .setWindow(xcb_window);
+
+            auto result =
+                inst.createXcbSurfaceKHR(&createInfo, nullptr, &surface);
+            VERIFY(result == vk::Result::eSuccess);
+#endif
+        }
+
+        // Iterate over each queue to learn whether it supports presenting:
+        std::unique_ptr<vk::Bool32[]> supportsPresent(
+            new vk::Bool32[queue_family_count]);
+        for (uint32_t i = 0; i < queue_family_count; i++) {
+            gpu.getSurfaceSupportKHR(i, surface, &supportsPresent[i]);
+        }
+
+        uint32_t graphicsQueueFamilyIndex = UINT32_MAX;
+        uint32_t presentQueueFamilyIndex = UINT32_MAX;
+        for (uint32_t i = 0; i < queue_family_count; i++) {
+            if (queue_props[i].queueFlags & vk::QueueFlagBits::eGraphics) {
+                if (graphicsQueueFamilyIndex == UINT32_MAX) {
+                    graphicsQueueFamilyIndex = i;
+                }
+
+                if (supportsPresent[i] == VK_TRUE) {
+                    graphicsQueueFamilyIndex = i;
+                    presentQueueFamilyIndex = i;
+                    break;
+                }
+            }
+        }
+
+        if (presentQueueFamilyIndex == UINT32_MAX) {
+            // If didn't find a queue that supports both graphics and present,
+            // then
+            // find a separate present queue.
+            for (uint32_t i = 0; i < queue_family_count; ++i) {
+                if (supportsPresent[i] == VK_TRUE) {
+                    presentQueueFamilyIndex = i;
+                    break;
+                }
+            }
+        }
+
+        // Generate error if could not find both a graphics and a present queue
+        if (graphicsQueueFamilyIndex == UINT32_MAX ||
+            presentQueueFamilyIndex == UINT32_MAX) {
+            ERR_EXIT("Could not find both graphics and present queues\n",
+                     "Swapchain Initialization Failure");
+        }
+
+        graphics_queue_family_index = graphicsQueueFamilyIndex;
+        present_queue_family_index = presentQueueFamilyIndex;
+        separate_present_queue =
+            (graphics_queue_family_index != present_queue_family_index);
+
+        create_device();
+
+        device.getQueue(graphics_queue_family_index, 0, &graphics_queue);
+        if (!separate_present_queue) {
+            present_queue = graphics_queue;
+        } else {
+            device.getQueue(present_queue_family_index, 0, &present_queue);
+        }
+
+        // Get the list of VkFormat's that are supported:
+        uint32_t formatCount;
+        auto result = gpu.getSurfaceFormatsKHR(surface, &formatCount, nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+
+        std::unique_ptr<vk::SurfaceFormatKHR[]> surfFormats(
+            new vk::SurfaceFormatKHR[formatCount]);
+        result =
+            gpu.getSurfaceFormatsKHR(surface, &formatCount, surfFormats.get());
+        VERIFY(result == vk::Result::eSuccess);
+
+        // If the format list includes just one entry of VK_FORMAT_UNDEFINED,
+        // the surface has no preferred format.  Otherwise, at least one
+        // supported format will be returned.
+        if (formatCount == 1 &&
+            surfFormats[0].format == vk::Format::eUndefined) {
+            format = vk::Format::eB8G8R8A8Unorm;
+        } else {
+            assert(formatCount >= 1);
+            format = surfFormats[0].format;
+        }
+        color_space = surfFormats[0].colorSpace;
+
+        quit = false;
+        curFrame = 0;
+
+        // Create semaphores to synchronize acquiring presentable buffers before
+        // rendering and waiting for drawing to be complete before presenting
+        auto const semaphoreCreateInfo = vk::SemaphoreCreateInfo();
+
+        // Create fences that we can use to throttle if we get too far
+        // ahead of the image presents
+        vk::FenceCreateInfo const fence_ci;
+        for (uint32_t i = 0; i < FRAME_LAG; i++) {
+            device.createFence(&fence_ci, nullptr, &fences[i]);
+            fencesInited[i] = false;
+            result = device.createSemaphore(&semaphoreCreateInfo, nullptr,
+                                            &image_acquired_semaphores[i]);
+            VERIFY(result == vk::Result::eSuccess);
+
+            result = device.createSemaphore(&semaphoreCreateInfo, nullptr,
+                                            &draw_complete_semaphores[i]);
+            VERIFY(result == vk::Result::eSuccess);
+
+            if (separate_present_queue) {
+                result = device.createSemaphore(&semaphoreCreateInfo, nullptr,
+                                                &image_ownership_semaphores[i]);
+                VERIFY(result == vk::Result::eSuccess);
+            }
+        }
+        frame_index = 0;
+
+        // Get Memory information and properties
+        gpu.getMemoryProperties(&memory_properties);
+    }
+
+    void prepare() {
+        auto const cmd_pool_info =
+            vk::CommandPoolCreateInfo().setQueueFamilyIndex(
+                graphics_queue_family_index);
+        auto result =
+            device.createCommandPool(&cmd_pool_info, nullptr, &cmd_pool);
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto const cmd = vk::CommandBufferAllocateInfo()
+                             .setCommandPool(cmd_pool)
+                             .setLevel(vk::CommandBufferLevel::ePrimary)
+                             .setCommandBufferCount(1);
+
+        prepare_buffers();
+        prepare_depth();
+        prepare_textures();
+        prepare_cube_data_buffer();
+
+        prepare_descriptor_layout();
+        prepare_render_pass();
+        prepare_pipeline();
+
+        for (uint32_t i = 0; i < swapchainImageCount; ++i) {
+            result = device.allocateCommandBuffers(&cmd, &buffers[i].cmd);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+
+        if (separate_present_queue) {
+            auto const cmd_pool_info =
+                vk::CommandPoolCreateInfo().setQueueFamilyIndex(
+                    present_queue_family_index);
+
+            result = device.createCommandPool(&cmd_pool_info, nullptr,
+                                              &present_cmd_pool);
+            VERIFY(result == vk::Result::eSuccess);
+
+            auto const cmd = vk::CommandBufferAllocateInfo()
+                                 .setCommandPool(present_cmd_pool)
+                                 .setLevel(vk::CommandBufferLevel::ePrimary)
+                                 .setCommandBufferCount(1);
+
+            for (uint32_t i = 0; i < swapchainImageCount; i++) {
+                result = device.allocateCommandBuffers(
+                    &cmd, &buffers[i].graphics_to_present_cmd);
+                VERIFY(result == vk::Result::eSuccess);
+
+                build_image_ownership_cmd(i);
+            }
+        }
+
+        prepare_descriptor_pool();
+        prepare_descriptor_set();
+
+        prepare_framebuffers();
+
+        for (uint32_t i = 0; i < swapchainImageCount; ++i) {
+            current_buffer = i;
+            draw_build_cmd(buffers[i].cmd);
+        }
+
+        /*
+         * Prepare functions above may generate pipeline commands
+         * that need to be flushed before beginning the render loop.
+         */
+        flush_init_cmd();
+
+        current_buffer = 0;
+        prepared = true;
+    }
+
+    void prepare_buffers() {
+        vk::SwapchainKHR oldSwapchain = swapchain;
+
+        // Check the surface capabilities and formats
+        vk::SurfaceCapabilitiesKHR surfCapabilities;
+        auto result = gpu.getSurfaceCapabilitiesKHR(surface, &surfCapabilities);
+        VERIFY(result == vk::Result::eSuccess);
+
+        uint32_t presentModeCount;
+        result =
+            gpu.getSurfacePresentModesKHR(surface, &presentModeCount, nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+
+        std::unique_ptr<vk::PresentModeKHR[]> presentModes(
+            new vk::PresentModeKHR[presentModeCount]);
+        result = gpu.getSurfacePresentModesKHR(surface, &presentModeCount,
+                                               presentModes.get());
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::Extent2D swapchainExtent;
+        // width and height are either both -1, or both not -1.
+        if (surfCapabilities.currentExtent.width == (uint32_t)-1) {
+            // If the surface size is undefined, the size is set to
+            // the size of the images requested.
+            swapchainExtent.width = width;
+            swapchainExtent.height = height;
+        } else {
+            // If the surface size is defined, the swap chain size must match
+            swapchainExtent = surfCapabilities.currentExtent;
+            width = surfCapabilities.currentExtent.width;
+            height = surfCapabilities.currentExtent.height;
+        }
+
+        // The FIFO present mode is guaranteed by the spec to be supported
+        // and to have no tearing.  It's a great default present mode to use.
+        vk::PresentModeKHR swapchainPresentMode = vk::PresentModeKHR::eFifo;
+
+//  There are times when you may wish to use another present mode.  The
+//  following code shows how to select them, and the comments provide some
+//  reasons you may wish to use them.
+//
+// It should be noted that Vulkan 1.0 doesn't provide a method for
+// synchronizing rendering with the presentation engine's display.  There
+// is a method provided for throttling rendering with the display, but
+// there are some presentation engines for which this method will not work.
+// If an application doesn't throttle its rendering, and if it renders much
+// faster than the refresh rate of the display, this can waste power on
+// mobile devices.  That is because power is being spent rendering images
+// that may never be seen.
+//#define DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR
+//#define DESIRE_VK_PRESENT_MODE_MAILBOX_KHR
+//#define DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR
+#if defined(DESIRE_VK_PRESENT_MODE_IMMEDIATE_KHR)
+        // VK_PRESENT_MODE_IMMEDIATE_KHR is for applications that don't care
+        // about
+        // tearing, or have some way of synchronizing their rendering with the
+        // display.
+        for (size_t i = 0; i < presentModeCount; ++i) {
+            if (presentModes[i] == vk::PresentModeKHR::eImmediate) {
+                swapchainPresentMode = vk::PresentModeKHR::eImmediate;
+                break;
+            }
+        }
+#elif defined(DESIRE_VK_PRESENT_MODE_MAILBOX_KHR)
+        // VK_PRESENT_MODE_MAILBOX_KHR may be useful for applications that
+        // generally render a new presentable image every refresh cycle, but are
+        // occasionally early.  In this case, the application wants the new
+        // image
+        // to be displayed instead of the previously-queued-for-presentation
+        // image
+        // that has not yet been displayed.
+        for (size_t i = 0; i < presentModeCount; ++i) {
+            if (presentModes[i] == vk::PresentModeKHR::eMailbox) {
+                swapchainPresentMode = vk::PresentModeKHR::eMailbox;
+                break;
+            }
+        }
+#elif defined(DESIRE_VK_PRESENT_MODE_FIFO_RELAXED_KHR)
+        // VK_PRESENT_MODE_FIFO_RELAXED_KHR is for applications that generally
+        // render a new presentable image every refresh cycle, but are
+        // occasionally
+        // late.  In this case (perhaps because of stuttering/latency concerns),
+        // the application wants the late image to be immediately displayed,
+        // even
+        // though that may mean some tearing.
+        for (size_t i = 0; i < presentModeCount; ++i) {
+            if (presentModes[i] == vk::PresentModeKHR::eFifoRelaxed) {
+                swapchainPresentMode = vk::PresentModeKHR::eFifoRelaxed;
+                break;
+            }
+        }
+#endif
+
+        // Determine the number of VkImage's to use in the swap chain (we desire
+        // to
+        // own only 1 image at a time, besides the images being displayed and
+        // queued for display):
+        uint32_t desiredNumberOfSwapchainImages =
+            surfCapabilities.minImageCount + 1;
+        // If maxImageCount is 0, we can ask for as many images as we want,
+        // otherwise
+        // we're limited to maxImageCount
+        if ((surfCapabilities.maxImageCount > 0) &&
+            (desiredNumberOfSwapchainImages > surfCapabilities.maxImageCount)) {
+            // Application must settle for fewer images than desired:
+            desiredNumberOfSwapchainImages = surfCapabilities.maxImageCount;
+        }
+
+        vk::SurfaceTransformFlagBitsKHR preTransform;
+        if (surfCapabilities.supportedTransforms &
+            vk::SurfaceTransformFlagBitsKHR::eIdentity) {
+            preTransform = vk::SurfaceTransformFlagBitsKHR::eIdentity;
+        } else {
+            preTransform = surfCapabilities.currentTransform;
+        }
+
+        auto const swapchain_ci =
+            vk::SwapchainCreateInfoKHR()
+                .setSurface(surface)
+                .setMinImageCount(desiredNumberOfSwapchainImages)
+                .setImageFormat(format)
+                .setImageColorSpace(color_space)
+                .setImageExtent({swapchainExtent.width, swapchainExtent.height})
+                .setImageArrayLayers(1)
+                .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment)
+                .setImageSharingMode(vk::SharingMode::eExclusive)
+                .setQueueFamilyIndexCount(0)
+                .setPQueueFamilyIndices(nullptr)
+                .setPreTransform(preTransform)
+                .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
+                .setPresentMode(swapchainPresentMode)
+                .setClipped(true)
+                .setOldSwapchain(oldSwapchain);
+
+        result = device.createSwapchainKHR(&swapchain_ci, nullptr, &swapchain);
+        VERIFY(result == vk::Result::eSuccess);
+
+        // If we just re-created an existing swapchain, we should destroy the
+        // old
+        // swapchain at this point.
+        // Note: destroying the swapchain also cleans up all its associated
+        // presentable images once the platform is done with them.
+        if (oldSwapchain) {
+            device.destroySwapchainKHR(oldSwapchain, nullptr);
+        }
+
+        result = device.getSwapchainImagesKHR(swapchain, &swapchainImageCount,
+                                              nullptr);
+        VERIFY(result == vk::Result::eSuccess);
+
+        std::unique_ptr<vk::Image[]> swapchainImages(
+            new vk::Image[swapchainImageCount]);
+        result = device.getSwapchainImagesKHR(swapchain, &swapchainImageCount,
+                                              swapchainImages.get());
+        VERIFY(result == vk::Result::eSuccess);
+
+        buffers.reset(new SwapchainBuffers[swapchainImageCount]);
+
+        for (uint32_t i = 0; i < swapchainImageCount; ++i) {
+            auto const color_image_view =
+                vk::ImageViewCreateInfo()
+                    .setImage(swapchainImages[i])
+                    .setViewType(vk::ImageViewType::e2D)
+                    .setFormat(format)
+                    .setSubresourceRange(vk::ImageSubresourceRange(
+                        vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
+
+            buffers[i].image = swapchainImages[i];
+
+            result = device.createImageView(&color_image_view, nullptr,
+                                            &buffers[i].view);
+            VERIFY(result == vk::Result::eSuccess);
+
+            // The draw loop will be expecting the presentable images to be in
+            // LAYOUT_PRESENT_SRC_KHR since that's how they're left at the end
+            // of every frame.
+            set_image_layout(buffers[i].image, vk::ImageAspectFlagBits::eColor,
+                             vk::ImageLayout::eUndefined,
+                             vk::ImageLayout::ePresentSrcKHR,
+                             vk::AccessFlagBits());
+        }
+    }
+
+    void prepare_cube_data_buffer() {
+        mat4x4 VP;
+        mat4x4_mul(VP, projection_matrix, view_matrix);
+
+        mat4x4 MVP;
+        mat4x4_mul(MVP, VP, model_matrix);
+
+        vktexcube_vs_uniform data;
+        memcpy(data.mvp, MVP, sizeof(MVP));
+        //    dumpMatrix("MVP", MVP)
+        for (int32_t i = 0; i < 12 * 3; i++) {
+            data.position[i][0] = g_vertex_buffer_data[i * 3];
+            data.position[i][1] = g_vertex_buffer_data[i * 3 + 1];
+            data.position[i][2] = g_vertex_buffer_data[i * 3 + 2];
+            data.position[i][3] = 1.0f;
+            data.attr[i][0] = g_uv_buffer_data[2 * i];
+            data.attr[i][1] = g_uv_buffer_data[2 * i + 1];
+            data.attr[i][2] = 0;
+            data.attr[i][3] = 0;
+        }
+
+        auto const buf_info =
+            vk::BufferCreateInfo()
+                .setSize(sizeof(data))
+                .setUsage(vk::BufferUsageFlagBits::eUniformBuffer);
+        auto result =
+            device.createBuffer(&buf_info, nullptr, &uniform_data.buf);
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::MemoryRequirements mem_reqs;
+        device.getBufferMemoryRequirements(uniform_data.buf, &mem_reqs);
+
+        uniform_data.mem_alloc.setAllocationSize(mem_reqs.size);
+        uniform_data.mem_alloc.setMemoryTypeIndex(0);
+
+        bool const pass = memory_type_from_properties(
+            mem_reqs.memoryTypeBits,
+            vk::MemoryPropertyFlagBits::eHostVisible |
+                vk::MemoryPropertyFlagBits::eHostCoherent,
+            &uniform_data.mem_alloc.memoryTypeIndex);
+        VERIFY(pass);
+
+        result = device.allocateMemory(&uniform_data.mem_alloc, nullptr,
+                                       &(uniform_data.mem));
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto pData = device.mapMemory(uniform_data.mem, 0,
+                                      uniform_data.mem_alloc.allocationSize,
+                                      vk::MemoryMapFlags());
+        VERIFY(pData.result == vk::Result::eSuccess);
+
+        memcpy(pData.value, &data, sizeof data);
+
+        device.unmapMemory(uniform_data.mem);
+
+        result = device.bindBufferMemory(uniform_data.buf, uniform_data.mem, 0);
+        VERIFY(result == vk::Result::eSuccess);
+
+        uniform_data.buffer_info.buffer = uniform_data.buf;
+        uniform_data.buffer_info.offset = 0;
+        uniform_data.buffer_info.range = sizeof(data);
+    }
+
+    void prepare_depth() {
+        depth.format = vk::Format::eD16Unorm;
+
+        auto const image =
+            vk::ImageCreateInfo()
+                .setImageType(vk::ImageType::e2D)
+                .setFormat(depth.format)
+                .setExtent({(uint32_t)width, (uint32_t)height, 1})
+                .setMipLevels(1)
+                .setArrayLayers(1)
+                .setSamples(vk::SampleCountFlagBits::e1)
+                .setTiling(vk::ImageTiling::eOptimal)
+                .setUsage(vk::ImageUsageFlagBits::eDepthStencilAttachment)
+                .setSharingMode(vk::SharingMode::eExclusive)
+                .setQueueFamilyIndexCount(0)
+                .setPQueueFamilyIndices(nullptr)
+                .setInitialLayout(vk::ImageLayout::eUndefined);
+
+        auto result = device.createImage(&image, nullptr, &depth.image);
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::MemoryRequirements mem_reqs;
+        device.getImageMemoryRequirements(depth.image, &mem_reqs);
+
+        depth.mem_alloc.setAllocationSize(mem_reqs.size);
+        depth.mem_alloc.setMemoryTypeIndex(0);
+
+        auto const pass = memory_type_from_properties(
+            mem_reqs.memoryTypeBits, vk::MemoryPropertyFlagBits(0),
+            &depth.mem_alloc.memoryTypeIndex);
+        VERIFY(pass);
+
+        result = device.allocateMemory(&depth.mem_alloc, nullptr, &depth.mem);
+        VERIFY(result == vk::Result::eSuccess);
+
+        result = device.bindImageMemory(depth.image, depth.mem, 0);
+        VERIFY(result == vk::Result::eSuccess);
+
+        set_image_layout(depth.image, vk::ImageAspectFlagBits::eDepth,
+                         vk::ImageLayout::eUndefined,
+                         vk::ImageLayout::eDepthStencilAttachmentOptimal,
+                         vk::AccessFlagBits());
+
+        auto const view = vk::ImageViewCreateInfo()
+                              .setImage(depth.image)
+                              .setViewType(vk::ImageViewType::e2D)
+                              .setFormat(depth.format)
+                              .setSubresourceRange(vk::ImageSubresourceRange(
+                                  vk::ImageAspectFlagBits::eDepth, 0, 1, 0, 1));
+        result = device.createImageView(&view, nullptr, &depth.view);
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    void prepare_descriptor_layout() {
+        vk::DescriptorSetLayoutBinding const layout_bindings[2] = {
+            vk::DescriptorSetLayoutBinding()
+                .setBinding(0)
+                .setDescriptorType(vk::DescriptorType::eUniformBuffer)
+                .setDescriptorCount(1)
+                .setStageFlags(vk::ShaderStageFlagBits::eVertex)
+                .setPImmutableSamplers(nullptr),
+            vk::DescriptorSetLayoutBinding()
+                .setBinding(1)
+                .setDescriptorType(vk::DescriptorType::eCombinedImageSampler)
+                .setDescriptorCount(texture_count)
+                .setStageFlags(vk::ShaderStageFlagBits::eFragment)
+                .setPImmutableSamplers(nullptr)};
+
+        auto const descriptor_layout =
+            vk::DescriptorSetLayoutCreateInfo().setBindingCount(2).setPBindings(
+                layout_bindings);
+
+        auto result = device.createDescriptorSetLayout(&descriptor_layout,
+                                                       nullptr, &desc_layout);
+        VERIFY(result == vk::Result::eSuccess);
+
+        auto const pPipelineLayoutCreateInfo =
+            vk::PipelineLayoutCreateInfo().setSetLayoutCount(1).setPSetLayouts(
+                &desc_layout);
+
+        result = device.createPipelineLayout(&pPipelineLayoutCreateInfo,
+                                             nullptr, &pipeline_layout);
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    void prepare_descriptor_pool() {
+        vk::DescriptorPoolSize const poolSizes[2] = {
+            vk::DescriptorPoolSize()
+                .setType(vk::DescriptorType::eUniformBuffer)
+                .setDescriptorCount(1),
+            vk::DescriptorPoolSize()
+                .setType(vk::DescriptorType::eCombinedImageSampler)
+                .setDescriptorCount(texture_count)};
+
+        auto const descriptor_pool = vk::DescriptorPoolCreateInfo()
+                                         .setMaxSets(1)
+                                         .setPoolSizeCount(2)
+                                         .setPPoolSizes(poolSizes);
+
+        auto result =
+            device.createDescriptorPool(&descriptor_pool, nullptr, &desc_pool);
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    void prepare_descriptor_set() {
+        auto const alloc_info = vk::DescriptorSetAllocateInfo()
+                                    .setDescriptorPool(desc_pool)
+                                    .setDescriptorSetCount(1)
+                                    .setPSetLayouts(&desc_layout);
+        auto result = device.allocateDescriptorSets(&alloc_info, &desc_set);
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::DescriptorImageInfo tex_descs[texture_count];
+        for (uint32_t i = 0; i < texture_count; i++) {
+            tex_descs[i].setSampler(textures[i].sampler);
+            tex_descs[i].setImageView(textures[i].view);
+            tex_descs[i].setImageLayout(vk::ImageLayout::eGeneral);
+        }
+
+        vk::WriteDescriptorSet writes[2];
+
+        writes[0].setDstSet(desc_set);
+        writes[0].setDescriptorCount(1);
+        writes[0].setDescriptorType(vk::DescriptorType::eUniformBuffer);
+        writes[0].setPBufferInfo(&uniform_data.buffer_info);
+
+        writes[1].setDstSet(desc_set);
+        writes[1].setDstBinding(1);
+        writes[1].setDescriptorCount(texture_count);
+        writes[1].setDescriptorType(vk::DescriptorType::eCombinedImageSampler);
+        writes[1].setPImageInfo(tex_descs);
+
+        device.updateDescriptorSets(2, writes, 0, nullptr);
+    }
+
+    void prepare_framebuffers() {
+        vk::ImageView attachments[2];
+        attachments[1] = depth.view;
+
+        auto const fb_info = vk::FramebufferCreateInfo()
+                                 .setRenderPass(render_pass)
+                                 .setAttachmentCount(2)
+                                 .setPAttachments(attachments)
+                                 .setWidth((uint32_t)width)
+                                 .setHeight((uint32_t)height)
+                                 .setLayers(1);
+
+        framebuffers.reset(new vk::Framebuffer[swapchainImageCount]);
+
+        for (uint32_t i = 0; i < swapchainImageCount; i++) {
+            attachments[0] = buffers[i].view;
+            auto const result =
+                device.createFramebuffer(&fb_info, nullptr, &framebuffers[i]);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+    }
+
+    vk::ShaderModule prepare_fs() {
+        size_t size = 0;
+        void *fragShaderCode = read_spv("cube-frag.spv", &size);
+
+        frag_shader_module = prepare_shader_module(fragShaderCode, size);
+
+        free(fragShaderCode);
+
+        return frag_shader_module;
+    }
+
+    void prepare_pipeline() {
+        vk::PipelineCacheCreateInfo const pipelineCacheInfo;
+        auto result = device.createPipelineCache(&pipelineCacheInfo, nullptr,
+                                                 &pipelineCache);
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::PipelineShaderStageCreateInfo const shaderStageInfo[2] = {
+            vk::PipelineShaderStageCreateInfo()
+                .setStage(vk::ShaderStageFlagBits::eVertex)
+                .setModule(prepare_vs())
+                .setPName("main"),
+            vk::PipelineShaderStageCreateInfo()
+                .setStage(vk::ShaderStageFlagBits::eFragment)
+                .setModule(prepare_fs())
+                .setPName("main")};
+
+        vk::PipelineVertexInputStateCreateInfo const vertexInputInfo;
+
+        auto const inputAssemblyInfo =
+            vk::PipelineInputAssemblyStateCreateInfo().setTopology(
+                vk::PrimitiveTopology::eTriangleList);
+
+        // TODO: Where are pViewports and pScissors set?
+        auto const viewportInfo = vk::PipelineViewportStateCreateInfo()
+                                      .setViewportCount(1)
+                                      .setScissorCount(1);
+
+        auto const rasterizationInfo =
+            vk::PipelineRasterizationStateCreateInfo()
+                .setDepthClampEnable(VK_FALSE)
+                .setRasterizerDiscardEnable(VK_FALSE)
+                .setPolygonMode(vk::PolygonMode::eFill)
+                .setCullMode(vk::CullModeFlagBits::eBack)
+                .setFrontFace(vk::FrontFace::eCounterClockwise)
+                .setDepthBiasEnable(VK_FALSE)
+                .setLineWidth(1.0f);
+
+        auto const multisampleInfo = vk::PipelineMultisampleStateCreateInfo();
+
+        auto const stencilOp = vk::StencilOpState()
+                                   .setFailOp(vk::StencilOp::eKeep)
+                                   .setPassOp(vk::StencilOp::eKeep)
+                                   .setCompareOp(vk::CompareOp::eAlways);
+
+        auto const depthStencilInfo =
+            vk::PipelineDepthStencilStateCreateInfo()
+                .setDepthTestEnable(VK_TRUE)
+                .setDepthWriteEnable(VK_TRUE)
+                .setDepthCompareOp(vk::CompareOp::eLessOrEqual)
+                .setDepthBoundsTestEnable(VK_FALSE)
+                .setStencilTestEnable(VK_FALSE)
+                .setFront(stencilOp)
+                .setBack(stencilOp);
+
+        vk::PipelineColorBlendAttachmentState const colorBlendAttachments[1] = {
+            vk::PipelineColorBlendAttachmentState().setColorWriteMask(
+                vk::ColorComponentFlagBits::eR |
+                vk::ColorComponentFlagBits::eG |
+                vk::ColorComponentFlagBits::eB |
+                vk::ColorComponentFlagBits::eA)};
+
+        auto const colorBlendInfo = vk::PipelineColorBlendStateCreateInfo()
+                                        .setAttachmentCount(1)
+                                        .setPAttachments(colorBlendAttachments);
+
+        vk::DynamicState const dynamicStates[2] = {vk::DynamicState::eViewport,
+                                                   vk::DynamicState::eScissor};
+
+        auto const dynamicStateInfo = vk::PipelineDynamicStateCreateInfo()
+                                          .setPDynamicStates(dynamicStates)
+                                          .setDynamicStateCount(2);
+
+        auto const pipeline = vk::GraphicsPipelineCreateInfo()
+                                  .setStageCount(2)
+                                  .setPStages(shaderStageInfo)
+                                  .setPVertexInputState(&vertexInputInfo)
+                                  .setPInputAssemblyState(&inputAssemblyInfo)
+                                  .setPViewportState(&viewportInfo)
+                                  .setPRasterizationState(&rasterizationInfo)
+                                  .setPMultisampleState(&multisampleInfo)
+                                  .setPDepthStencilState(&depthStencilInfo)
+                                  .setPColorBlendState(&colorBlendInfo)
+                                  .setPDynamicState(&dynamicStateInfo)
+                                  .setLayout(pipeline_layout)
+                                  .setRenderPass(render_pass);
+
+        result = device.createGraphicsPipelines(pipelineCache, 1, &pipeline,
+                                                nullptr, &this->pipeline);
+        VERIFY(result == vk::Result::eSuccess);
+
+        device.destroyShaderModule(frag_shader_module, nullptr);
+        device.destroyShaderModule(vert_shader_module, nullptr);
+    }
+
+    void prepare_render_pass() {
+        const vk::AttachmentDescription attachments[2] = {
+            vk::AttachmentDescription()
+                .setFlags(vk::AttachmentDescriptionFlagBits::eMayAlias)
+                .setFormat(format)
+                .setSamples(vk::SampleCountFlagBits::e1)
+                .setLoadOp(vk::AttachmentLoadOp::eClear)
+                .setStoreOp(vk::AttachmentStoreOp::eStore)
+                .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
+                .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
+                .setInitialLayout(vk::ImageLayout::eColorAttachmentOptimal)
+                .setFinalLayout(vk::ImageLayout::ePresentSrcKHR),
+            vk::AttachmentDescription()
+                .setFlags(vk::AttachmentDescriptionFlagBits::eMayAlias)
+                .setFormat(depth.format)
+                .setSamples(vk::SampleCountFlagBits::e1)
+                .setLoadOp(vk::AttachmentLoadOp::eClear)
+                .setStoreOp(vk::AttachmentStoreOp::eDontCare)
+                .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
+                .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
+                .setInitialLayout(
+                    vk::ImageLayout::eDepthStencilAttachmentOptimal)
+                .setFinalLayout(
+                    vk::ImageLayout::eDepthStencilAttachmentOptimal)};
+
+        auto const color_reference =
+            vk::AttachmentReference().setAttachment(0).setLayout(
+                vk::ImageLayout::eColorAttachmentOptimal);
+
+        auto const depth_reference =
+            vk::AttachmentReference().setAttachment(1).setLayout(
+                vk::ImageLayout::eDepthStencilAttachmentOptimal);
+
+        auto const subpass =
+            vk::SubpassDescription()
+                .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
+                .setInputAttachmentCount(0)
+                .setPInputAttachments(nullptr)
+                .setColorAttachmentCount(1)
+                .setPColorAttachments(&color_reference)
+                .setPResolveAttachments(nullptr)
+                .setPDepthStencilAttachment(&depth_reference)
+                .setPreserveAttachmentCount(0)
+                .setPPreserveAttachments(nullptr);
+
+        auto const rp_info = vk::RenderPassCreateInfo()
+                                 .setAttachmentCount(2)
+                                 .setPAttachments(attachments)
+                                 .setSubpassCount(1)
+                                 .setPSubpasses(&subpass)
+                                 .setDependencyCount(0)
+                                 .setPDependencies(nullptr);
+
+        auto result = device.createRenderPass(&rp_info, nullptr, &render_pass);
+        VERIFY(result == vk::Result::eSuccess);
+    }
+
+    vk::ShaderModule prepare_shader_module(const void *code, size_t size) {
+        auto const moduleCreateInfo =
+            vk::ShaderModuleCreateInfo().setCodeSize(size).setPCode(
+                (uint32_t const *)code);
+
+        vk::ShaderModule module;
+        auto result =
+            device.createShaderModule(&moduleCreateInfo, nullptr, &module);
+        VERIFY(result == vk::Result::eSuccess);
+
+        return module;
+    }
+
+    void prepare_texture_image(const char *filename, texture_object *tex_obj,
+                               vk::ImageTiling tiling,
+                               vk::ImageUsageFlags usage,
+                               vk::MemoryPropertyFlags required_props) {
+        int32_t tex_width;
+        int32_t tex_height;
+        if (!loadTexture(filename, nullptr, nullptr, &tex_width, &tex_height)) {
+            ERR_EXIT("Failed to load textures", "Load Texture Failure");
+        }
+
+        tex_obj->tex_width = tex_width;
+        tex_obj->tex_height = tex_height;
+
+        auto const image_create_info =
+            vk::ImageCreateInfo()
+                .setImageType(vk::ImageType::e2D)
+                .setFormat(vk::Format::eR8G8B8A8Unorm)
+                .setExtent({(uint32_t)tex_width, (uint32_t)tex_height, 1})
+                .setMipLevels(1)
+                .setArrayLayers(1)
+                .setSamples(vk::SampleCountFlagBits::e1)
+                .setTiling(tiling)
+                .setUsage(usage)
+                .setSharingMode(vk::SharingMode::eExclusive)
+                .setQueueFamilyIndexCount(0)
+                .setPQueueFamilyIndices(nullptr)
+                .setInitialLayout(vk::ImageLayout::ePreinitialized);
+
+        auto result =
+            device.createImage(&image_create_info, nullptr, &tex_obj->image);
+        VERIFY(result == vk::Result::eSuccess);
+
+        vk::MemoryRequirements mem_reqs;
+        device.getImageMemoryRequirements(tex_obj->image, &mem_reqs);
+
+        tex_obj->mem_alloc.setAllocationSize(mem_reqs.size);
+        tex_obj->mem_alloc.setMemoryTypeIndex(0);
+
+        auto pass =
+            memory_type_from_properties(mem_reqs.memoryTypeBits, required_props,
+                                        &tex_obj->mem_alloc.memoryTypeIndex);
+        VERIFY(pass == true);
+
+        result = device.allocateMemory(&tex_obj->mem_alloc, nullptr,
+                                       &(tex_obj->mem));
+        VERIFY(result == vk::Result::eSuccess);
+
+        result = device.bindImageMemory(tex_obj->image, tex_obj->mem, 0);
+        VERIFY(result == vk::Result::eSuccess);
+
+        if (required_props & vk::MemoryPropertyFlagBits::eHostVisible) {
+            auto const subres =
+                vk::ImageSubresource()
+                    .setAspectMask(vk::ImageAspectFlagBits::eColor)
+                    .setMipLevel(0)
+                    .setArrayLayer(0);
+            vk::SubresourceLayout layout;
+            device.getImageSubresourceLayout(tex_obj->image, &subres, &layout);
+
+            auto data = device.mapMemory(tex_obj->mem, 0,
+                                         tex_obj->mem_alloc.allocationSize);
+            VERIFY(data.result == vk::Result::eSuccess);
+
+            if (!loadTexture(filename, (uint8_t *)data.value, &layout,
+                             &tex_width, &tex_height)) {
+                fprintf(stderr, "Error loading texture: %s\n", filename);
+            }
+
+            device.unmapMemory(tex_obj->mem);
+        }
+
+        tex_obj->imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
+        set_image_layout(tex_obj->image, vk::ImageAspectFlagBits::eColor,
+                         vk::ImageLayout::ePreinitialized, tex_obj->imageLayout,
+                         vk::AccessFlagBits::eHostWrite);
+    }
+
+    void prepare_textures() {
+        vk::Format const tex_format = vk::Format::eR8G8B8A8Unorm;
+        vk::FormatProperties props;
+        gpu.getFormatProperties(tex_format, &props);
+
+        for (uint32_t i = 0; i < texture_count; i++) {
+            if ((props.linearTilingFeatures &
+                 vk::FormatFeatureFlagBits::eSampledImage) &&
+                !use_staging_buffer) {
+                /* Device can texture using linear textures */
+                prepare_texture_image(
+                    tex_files[i], &textures[i], vk::ImageTiling::eLinear,
+                    vk::ImageUsageFlagBits::eSampled,
+                    vk::MemoryPropertyFlagBits::eHostVisible |
+                        vk::MemoryPropertyFlagBits::eHostCoherent);
+            } else if (props.optimalTilingFeatures &
+                       vk::FormatFeatureFlagBits::eSampledImage) {
+                /* Must use staging buffer to copy linear texture to optimized
+                 */
+                texture_object staging_texture;
+
+                prepare_texture_image(
+                    tex_files[i], &staging_texture, vk::ImageTiling::eLinear,
+                    vk::ImageUsageFlagBits::eTransferSrc,
+                    vk::MemoryPropertyFlagBits::eHostVisible |
+                        vk::MemoryPropertyFlagBits::eHostCoherent);
+
+                prepare_texture_image(tex_files[i], &textures[i],
+                                      vk::ImageTiling::eOptimal,
+                                      vk::ImageUsageFlagBits::eTransferDst |
+                                          vk::ImageUsageFlagBits::eSampled,
+                                      vk::MemoryPropertyFlagBits::eDeviceLocal);
+
+                set_image_layout(
+                    staging_texture.image, vk::ImageAspectFlagBits::eColor,
+                    staging_texture.imageLayout,
+                    vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlags());
+
+                set_image_layout(
+                    textures[i].image, vk::ImageAspectFlagBits::eColor,
+                    textures[i].imageLayout,
+                    vk::ImageLayout::eTransferDstOptimal, vk::AccessFlags());
+
+                auto const subresource =
+                    vk::ImageSubresourceLayers()
+                        .setAspectMask(vk::ImageAspectFlagBits::eColor)
+                        .setMipLevel(0)
+                        .setBaseArrayLayer(0)
+                        .setLayerCount(1);
+
+                auto const copy_region =
+                    vk::ImageCopy()
+                        .setSrcSubresource(subresource)
+                        .setSrcOffset({0, 0, 0})
+                        .setDstSubresource(subresource)
+                        .setDstOffset({0, 0, 0})
+                        .setExtent({(uint32_t)staging_texture.tex_width,
+                                    (uint32_t)staging_texture.tex_height, 1});
+
+                cmd.copyImage(
+                    staging_texture.image, vk::ImageLayout::eTransferSrcOptimal,
+                    textures[i].image, vk::ImageLayout::eTransferDstOptimal, 1,
+                    &copy_region);
+
+                set_image_layout(textures[i].image,
+                                 vk::ImageAspectFlagBits::eColor,
+                                 vk::ImageLayout::eTransferDstOptimal,
+                                 textures[i].imageLayout, vk::AccessFlags());
+
+                flush_init_cmd();
+
+                destroy_texture_image(&staging_texture);
+            } else {
+                assert(
+                    !"No support for R8G8B8A8_UNORM as texture image format");
+            }
+
+            auto const samplerInfo =
+                vk::SamplerCreateInfo()
+                    .setMagFilter(vk::Filter::eNearest)
+                    .setMinFilter(vk::Filter::eNearest)
+                    .setMipmapMode(vk::SamplerMipmapMode::eNearest)
+                    .setAddressModeU(vk::SamplerAddressMode::eClampToEdge)
+                    .setAddressModeV(vk::SamplerAddressMode::eClampToEdge)
+                    .setAddressModeW(vk::SamplerAddressMode::eClampToEdge)
+                    .setMipLodBias(0.0f)
+                    .setAnisotropyEnable(VK_FALSE)
+                    .setMaxAnisotropy(1)
+                    .setCompareEnable(VK_FALSE)
+                    .setCompareOp(vk::CompareOp::eNever)
+                    .setMinLod(0.0f)
+                    .setMaxLod(0.0f)
+                    .setBorderColor(vk::BorderColor::eFloatOpaqueWhite)
+                    .setUnnormalizedCoordinates(VK_FALSE);
+
+            auto result = device.createSampler(&samplerInfo, nullptr,
+                                               &textures[i].sampler);
+            VERIFY(result == vk::Result::eSuccess);
+
+            auto const viewInfo =
+                vk::ImageViewCreateInfo()
+                    .setImage(textures[i].image)
+                    .setViewType(vk::ImageViewType::e2D)
+                    .setFormat(tex_format)
+                    .setSubresourceRange(vk::ImageSubresourceRange(
+                        vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1));
+
+            result =
+                device.createImageView(&viewInfo, nullptr, &textures[i].view);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+    }
+
+    vk::ShaderModule prepare_vs() {
+        size_t size = 0;
+        void *vertShaderCode = read_spv("cube-vert.spv", &size);
+
+        vert_shader_module = prepare_shader_module(vertShaderCode, size);
+
+        free(vertShaderCode);
+
+        return vert_shader_module;
+    }
+
+    char *read_spv(const char *filename, size_t *psize) {
+        FILE *fp = fopen(filename, "rb");
+        if (!fp) {
+            return nullptr;
+        }
+
+        fseek(fp, 0L, SEEK_END);
+        long int size = ftell(fp);
+
+        fseek(fp, 0L, SEEK_SET);
+
+        void *shader_code = malloc(size);
+        size_t retval = fread(shader_code, size, 1, fp);
+        VERIFY(retval == 1);
+
+        *psize = size;
+
+        fclose(fp);
+
+        return (char *)shader_code;
+    }
+
+    void resize() {
+        uint32_t i;
+
+        // Don't react to resize until after first initialization.
+        if (!prepared) {
+            return;
+        }
+
+        // In order to properly resize the window, we must re-create the
+        // swapchain
+        // AND redo the command buffers, etc.
+        //
+        // First, perform part of the cleanup() function:
+        prepared = false;
+        auto result = device.waitIdle();
+        VERIFY(result == vk::Result::eSuccess);
+
+        for (i = 0; i < swapchainImageCount; i++) {
+            device.destroyFramebuffer(framebuffers[i], nullptr);
+        }
+
+        device.destroyDescriptorPool(desc_pool, nullptr);
+
+        device.destroyPipeline(pipeline, nullptr);
+        device.destroyPipelineCache(pipelineCache, nullptr);
+        device.destroyRenderPass(render_pass, nullptr);
+        device.destroyPipelineLayout(pipeline_layout, nullptr);
+        device.destroyDescriptorSetLayout(desc_layout, nullptr);
+
+        for (i = 0; i < texture_count; i++) {
+            device.destroyImageView(textures[i].view, nullptr);
+            device.destroyImage(textures[i].image, nullptr);
+            device.freeMemory(textures[i].mem, nullptr);
+            device.destroySampler(textures[i].sampler, nullptr);
+        }
+
+        device.destroyImageView(depth.view, nullptr);
+        device.destroyImage(depth.image, nullptr);
+        device.freeMemory(depth.mem, nullptr);
+
+        device.destroyBuffer(uniform_data.buf, nullptr);
+        device.freeMemory(uniform_data.mem, nullptr);
+
+        for (i = 0; i < swapchainImageCount; i++) {
+            device.destroyImageView(buffers[i].view, nullptr);
+            device.freeCommandBuffers(cmd_pool, 1, &buffers[i].cmd);
+        }
+
+        device.destroyCommandPool(cmd_pool, nullptr);
+        if (separate_present_queue) {
+            device.destroyCommandPool(present_cmd_pool, nullptr);
+        }
+
+        // Second, re-perform the prepare() function, which will re-create the
+        // swapchain.
+        prepare();
+    }
+
+    void set_image_layout(vk::Image image, vk::ImageAspectFlags aspectMask,
+                          vk::ImageLayout oldLayout, vk::ImageLayout newLayout,
+                          vk::AccessFlags srcAccessMask) {
+        if (!cmd) {
+            auto const cmd = vk::CommandBufferAllocateInfo()
+                                 .setCommandPool(cmd_pool)
+                                 .setLevel(vk::CommandBufferLevel::ePrimary)
+                                 .setCommandBufferCount(1);
+
+            auto result = device.allocateCommandBuffers(&cmd, &this->cmd);
+            VERIFY(result == vk::Result::eSuccess);
+
+            auto const cmd_buf_info =
+                vk::CommandBufferBeginInfo().setPInheritanceInfo(nullptr);
+
+            result = this->cmd.begin(&cmd_buf_info);
+            VERIFY(result == vk::Result::eSuccess);
+        }
+
+        auto DstAccessMask = [](vk::ImageLayout const &layout) {
+            vk::AccessFlags flags;
+
+            switch (layout) {
+            case vk::ImageLayout::eTransferDstOptimal:
+                // Make sure anything that was copying from this image has
+                // completed
+                flags = vk::AccessFlagBits::eTransferRead;
+                break;
+            case vk::ImageLayout::eColorAttachmentOptimal:
+                flags = vk::AccessFlagBits::eColorAttachmentWrite;
+                break;
+            case vk::ImageLayout::eDepthStencilAttachmentOptimal:
+                flags = vk::AccessFlagBits::eDepthStencilAttachmentWrite;
+                break;
+            case vk::ImageLayout::eShaderReadOnlyOptimal:
+                // Make sure any Copy or CPU writes to image are flushed
+                flags = vk::AccessFlagBits::eShaderRead |
+                        vk::AccessFlagBits::eInputAttachmentRead;
+                break;
+            case vk::ImageLayout::ePresentSrcKHR:
+                flags = vk::AccessFlagBits::eMemoryRead;
+                break;
+            default:
+                break;
+            }
+
+            return flags;
+        };
+
+        auto const barrier = vk::ImageMemoryBarrier()
+                                 .setSrcAccessMask(srcAccessMask)
+                                 .setDstAccessMask(DstAccessMask(newLayout))
+                                 .setOldLayout(oldLayout)
+                                 .setNewLayout(newLayout)
+                                 .setSrcQueueFamilyIndex(0)
+                                 .setDstQueueFamilyIndex(0)
+                                 .setImage(image)
+                                 .setSubresourceRange(vk::ImageSubresourceRange(
+                                     aspectMask, 0, 1, 0, 1));
+
+        cmd.pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
+                            vk::PipelineStageFlagBits::eTopOfPipe,
+                            vk::DependencyFlagBits(), 0, nullptr, 0, nullptr, 1,
+                            &barrier);
+    }
+
+    void update_data_buffer() {
+        mat4x4 VP;
+        mat4x4_mul(VP, projection_matrix, view_matrix);
+
+        // Rotate 22.5 degrees around the Y axis
+        mat4x4 Model;
+        mat4x4_dup(Model, model_matrix);
+        mat4x4_rotate(model_matrix, Model, 0.0f, 1.0f, 0.0f,
+                      (float)degreesToRadians(spin_angle));
+
+        mat4x4 MVP;
+        mat4x4_mul(MVP, VP, model_matrix);
+
+        auto data = device.mapMemory(uniform_data.mem, 0,
+                                     uniform_data.mem_alloc.allocationSize,
+                                     vk::MemoryMapFlags());
+        VERIFY(data.result == vk::Result::eSuccess);
+
+        memcpy(data.value, (const void *)&MVP[0][0], sizeof(MVP));
+
+        device.unmapMemory(uniform_data.mem);
+    }
+
+    bool loadTexture(const char *filename, uint8_t *rgba_data,
+                     vk::SubresourceLayout *layout, int32_t *width,
+                     int32_t *height) {
+        FILE *fPtr = fopen(filename, "rb");
+        if (!fPtr) {
+            return false;
+        }
+
+        char header[256];
+        char *cPtr = fgets(header, 256, fPtr); // P6
+        if (cPtr == nullptr || strncmp(header, "P6\n", 3)) {
+            fclose(fPtr);
+            return false;
+        }
+
+        do {
+            cPtr = fgets(header, 256, fPtr);
+            if (cPtr == nullptr) {
+                fclose(fPtr);
+                return false;
+            }
+        } while (!strncmp(header, "#", 1));
+
+        sscanf(header, "%u %u", width, height);
+        if (rgba_data == nullptr) {
+            fclose(fPtr);
+            return true;
+        }
+
+        char *result = fgets(header, 256, fPtr); // Format
+        VERIFY(result != nullptr);
+        if (cPtr == nullptr || strncmp(header, "255\n", 3)) {
+            fclose(fPtr);
+            return false;
+        }
+
+        for (int y = 0; y < *height; y++) {
+            uint8_t *rowPtr = rgba_data;
+
+            for (int x = 0; x < *width; x++) {
+                size_t s = fread(rowPtr, 3, 1, fPtr);
+                (void)s;
+                rowPtr[3] = 255; /* Alpha of 1 */
+                rowPtr += 4;
+            }
+
+            rgba_data += layout->rowPitch;
+        }
+
+        fclose(fPtr);
+        return true;
+    }
+
+    bool memory_type_from_properties(uint32_t typeBits,
+                                     vk::MemoryPropertyFlags requirements_mask,
+                                     uint32_t *typeIndex) {
+        // Search memtypes to find first index with those properties
+        for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
+            if ((typeBits & 1) == 1) {
+                // Type is available, does it match user properties?
+                if ((memory_properties.memoryTypes[i].propertyFlags &
+                     requirements_mask) == requirements_mask) {
+                    *typeIndex = i;
+                    return true;
+                }
+            }
+            typeBits >>= 1;
+        }
+
+        // No memory types matched, return failure
+        return false;
+    }
+
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    void run() {
+        if (!prepared) {
+            return;
+        }
+
+        update_data_buffer();
+        draw();
+        curFrame++;
+
+        if (frameCount != INT_MAX && curFrame == frameCount) {
+            PostQuitMessage(validation_error);
+        }
+    }
+
+    void create_window() {
+        WNDCLASSEX win_class;
+
+        // Initialize the window class structure:
+        win_class.cbSize = sizeof(WNDCLASSEX);
+        win_class.style = CS_HREDRAW | CS_VREDRAW;
+        win_class.lpfnWndProc = WndProc;
+        win_class.cbClsExtra = 0;
+        win_class.cbWndExtra = 0;
+        win_class.hInstance = connection; // hInstance
+        win_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
+        win_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
+        win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+        win_class.lpszMenuName = nullptr;
+        win_class.lpszClassName = name;
+        win_class.hIconSm = LoadIcon(nullptr, IDI_WINLOGO);
+
+        // Register window class:
+        if (!RegisterClassEx(&win_class)) {
+            // It didn't work, so try to give a useful error:
+            printf("Unexpected error trying to start the application!\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        // Create window with the registered class:
+        RECT wr = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
+        AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
+        window = CreateWindowEx(0,
+                                name,                 // class name
+                                name,                 // app name
+                                WS_OVERLAPPEDWINDOW | // window style
+                                    WS_VISIBLE | WS_SYSMENU,
+                                100, 100,           // x/y coords
+                                wr.right - wr.left, // width
+                                wr.bottom - wr.top, // height
+                                nullptr,            // handle to parent
+                                nullptr,            // handle to menu
+                                connection,         // hInstance
+                                nullptr);           // no extra parameters
+
+        if (!window) {
+            // It didn't work, so try to give a useful error:
+            printf("Cannot create a window in which to draw!\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        // Window client area size must be at least 1 pixel high, to prevent
+        // crash.
+        minsize.x = GetSystemMetrics(SM_CXMINTRACK);
+        minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1;
+    }
+
+#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+#if defined(VK_USE_PLATFORM_XLIB_KHR)
+
+    void create_xlib_window() {
+        display = XOpenDisplay(nullptr);
+        long visualMask = VisualScreenMask;
+        int numberOfVisuals;
+        XVisualInfo vInfoTemplate = {};
+        vInfoTemplate.screen = DefaultScreen(display);
+        XVisualInfo *visualInfo = XGetVisualInfo(
+            display, visualMask, &vInfoTemplate, &numberOfVisuals);
+
+        Colormap colormap =
+            XCreateColormap(display, RootWindow(display, vInfoTemplate.screen),
+                            visualInfo->visual, AllocNone);
+
+        XSetWindowAttributes windowAttributes = {};
+        windowAttributes.colormap = colormap;
+        windowAttributes.background_pixel = 0xFFFFFFFF;
+        windowAttributes.border_pixel = 0;
+        windowAttributes.event_mask =
+            KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask;
+
+        xlib_window = XCreateWindow(
+            display, RootWindow(display, vInfoTemplate.screen), 0, 0, width,
+            height, 0, visualInfo->depth, InputOutput, visualInfo->visual,
+            CWBackPixel | CWBorderPixel | CWEventMask | CWColormap,
+            &windowAttributes);
+
+        XSelectInput(display, xlib_window, ExposureMask | KeyPressMask);
+        XMapWindow(display, xlib_window);
+        XFlush(display);
+        xlib_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
+    }
+
+    void handle_xlib_event(const XEvent *event) {
+        switch (event->type) {
+        case ClientMessage:
+            if ((Atom)event->xclient.data.l[0] == xlib_wm_delete_window) {
+                quit = true;
+            }
+            break;
+        case KeyPress:
+            switch (event->xkey.keycode) {
+            case 0x9: // Escape
+                quit = true;
+                break;
+            case 0x71: // left arrow key
+                spin_angle += spin_increment;
+                break;
+            case 0x72: // right arrow key
+                spin_angle -= spin_increment;
+                break;
+            case 0x41:
+                pause = !pause;
+                break;
+            }
+            break;
+        case ConfigureNotify:
+            if (((int32_t)width != event->xconfigure.width) ||
+                ((int32_t)height != event->xconfigure.height)) {
+                width = event->xconfigure.width;
+                height = event->xconfigure.height;
+                resize();
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    void run_xlib() {
+        while (!quit) {
+            XEvent event;
+
+            if (pause) {
+                XNextEvent(display, &event);
+                handle_xlib_event(&event);
+            } else {
+                while (XPending(display) > 0) {
+                    XNextEvent(display, &event);
+                    handle_xlib_event(&event);
+                }
+            }
+
+            update_data_buffer();
+            draw();
+            curFrame++;
+
+            if (frameCount != UINT32_MAX && curFrame == frameCount) {
+                quit = true;
+            }
+        }
+    }
+
+#endif
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+
+    void handle_xcb_event(const xcb_generic_event_t *event) {
+        uint8_t event_code = event->response_type & 0x7f;
+        switch (event_code) {
+        case XCB_EXPOSE:
+            // TODO: Resize window
+            break;
+        case XCB_CLIENT_MESSAGE:
+            if ((*(xcb_client_message_event_t *)event).data.data32[0] ==
+                (*atom_wm_delete_window).atom) {
+                quit = true;
+            }
+            break;
+        case XCB_KEY_RELEASE: {
+            const xcb_key_release_event_t *key =
+                (const xcb_key_release_event_t *)event;
+
+            switch (key->detail) {
+            case 0x9: // Escape
+                quit = true;
+                break;
+            case 0x71: // left arrow key
+                spin_angle += spin_increment;
+                break;
+            case 0x72: // right arrow key
+                spin_angle -= spin_increment;
+                break;
+            case 0x41:
+                pause = !pause;
+                break;
+            }
+        } break;
+        case XCB_CONFIGURE_NOTIFY: {
+            const xcb_configure_notify_event_t *cfg =
+                (const xcb_configure_notify_event_t *)event;
+            if ((width != cfg->width) || (height != cfg->height)) {
+                width = cfg->width;
+                height = cfg->height;
+                resize();
+            }
+        } break;
+        default:
+            break;
+        }
+    }
+
+    void run_xcb() {
+        xcb_flush(connection);
+
+        while (!quit) {
+            xcb_generic_event_t *event;
+
+            if (pause) {
+                event = xcb_wait_for_event(connection);
+            } else {
+                event = xcb_poll_for_event(connection);
+                while (event) {
+                    handle_xcb_event(event);
+                    free(event);
+                    event = xcb_poll_for_event(connection);
+                }
+            }
+
+            update_data_buffer();
+            draw();
+            curFrame++;
+            if (frameCount != UINT32_MAX && curFrame == frameCount) {
+                quit = true;
+            }
+        }
+    }
+
+    void create_xcb_window() {
+        uint32_t value_mask, value_list[32];
+
+        xcb_window = xcb_generate_id(connection);
+
+        value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+        value_list[0] = screen->black_pixel;
+        value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE |
+                        XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+
+        xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window,
+                          screen->root, 0, 0, width, height, 0,
+                          XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual,
+                          value_mask, value_list);
+
+        /* Magic code that will send notification when window is destroyed */
+        xcb_intern_atom_cookie_t cookie =
+            xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
+        xcb_intern_atom_reply_t *reply =
+            xcb_intern_atom_reply(connection, cookie, 0);
+
+        xcb_intern_atom_cookie_t cookie2 =
+            xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
+        atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
+
+        xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window,
+                            (*reply).atom, 4, 32, 1,
+                            &(*atom_wm_delete_window).atom);
+
+        free(reply);
+
+        xcb_map_window(connection, xcb_window);
+
+        // Force the x/y coordinates to 100,100 results are identical in
+        // consecutive
+        // runs
+        const uint32_t coords[] = {100, 100};
+        xcb_configure_window(connection, xcb_window,
+                             XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
+    }
+
+#endif
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+
+    void run() {
+        while (!quit) {
+            update_data_buffer();
+            draw();
+            curFrame++;
+            if (frameCount != UINT32_MAX && curFrame == frameCount) {
+                quit = true;
+            }
+        }
+    }
+
+    void create_window() {
+        window = wl_compositor_create_surface(compositor);
+        if (!window) {
+            printf("Can not create wayland_surface from compositor!\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        shell_surface = wl_shell_get_shell_surface(shell, window);
+        if (!shell_surface) {
+            printf("Can not get shell_surface from wayland_surface!\n");
+            fflush(stdout);
+            exit(1);
+        }
+
+        wl_shell_surface_add_listener(shell_surface, &shell_surface_listener,
+                                      this);
+        wl_shell_surface_set_toplevel(shell_surface);
+        wl_shell_surface_set_title(shell_surface, APP_SHORT_NAME);
+    }
+
+#endif
+
+#if defined(VK_USE_PLATFORM_WIN32_KHR)
+    HINSTANCE connection;        // hInstance - Windows Instance
+    HWND window;                 // hWnd - window handle
+    POINT minsize;               // minimum window size
+    char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
+#elif defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR)
+    Display *display;
+    Window xlib_window;
+    Atom xlib_wm_delete_window;
+
+    xcb_connection_t *connection;
+    xcb_screen_t *screen;
+    xcb_window_t xcb_window;
+    xcb_intern_atom_reply_t *atom_wm_delete_window;
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    wl_display *display;
+    wl_registry *registry;
+    wl_compositor *compositor;
+    wl_surface *window;
+    wl_shell *shell;
+    wl_shell_surface *shell_surface;
+#endif
+
+    vk::SurfaceKHR surface;
+    bool prepared;
+    bool use_staging_buffer;
+    bool use_xlib;
+    bool separate_present_queue;
+
+    vk::Instance inst;
+    vk::PhysicalDevice gpu;
+    vk::Device device;
+    vk::Queue graphics_queue;
+    vk::Queue present_queue;
+    uint32_t graphics_queue_family_index;
+    uint32_t present_queue_family_index;
+    vk::Semaphore image_acquired_semaphores[FRAME_LAG];
+    vk::Semaphore draw_complete_semaphores[FRAME_LAG];
+    vk::Semaphore image_ownership_semaphores[FRAME_LAG];
+    vk::PhysicalDeviceProperties gpu_props;
+    std::unique_ptr<vk::QueueFamilyProperties[]> queue_props;
+    vk::PhysicalDeviceMemoryProperties memory_properties;
+
+    uint32_t enabled_extension_count;
+    uint32_t enabled_layer_count;
+    char const *extension_names[64];
+    char const *enabled_layers[64];
+
+    uint32_t width;
+    uint32_t height;
+    vk::Format format;
+    vk::ColorSpaceKHR color_space;
+
+    uint32_t swapchainImageCount;
+    vk::SwapchainKHR swapchain;
+    std::unique_ptr<SwapchainBuffers[]> buffers;
+    vk::Fence fences[FRAME_LAG];
+    bool fencesInited[FRAME_LAG];
+    uint32_t frame_index;
+
+    vk::CommandPool cmd_pool;
+    vk::CommandPool present_cmd_pool;
+
+    struct {
+        vk::Format format;
+        vk::Image image;
+        vk::MemoryAllocateInfo mem_alloc;
+        vk::DeviceMemory mem;
+        vk::ImageView view;
+    } depth;
+
+    static int32_t const texture_count = 1;
+    texture_object textures[texture_count];
+
+    struct {
+        vk::Buffer buf;
+        vk::MemoryAllocateInfo mem_alloc;
+        vk::DeviceMemory mem;
+        vk::DescriptorBufferInfo buffer_info;
+    } uniform_data;
+
+    vk::CommandBuffer cmd; // Buffer for initialization commands
+    vk::PipelineLayout pipeline_layout;
+    vk::DescriptorSetLayout desc_layout;
+    vk::PipelineCache pipelineCache;
+    vk::RenderPass render_pass;
+    vk::Pipeline pipeline;
+
+    mat4x4 projection_matrix;
+    mat4x4 view_matrix;
+    mat4x4 model_matrix;
+
+    float spin_angle;
+    float spin_increment;
+    bool pause;
+
+    vk::ShaderModule vert_shader_module;
+    vk::ShaderModule frag_shader_module;
+
+    vk::DescriptorPool desc_pool;
+    vk::DescriptorSet desc_set;
+
+    std::unique_ptr<vk::Framebuffer[]> framebuffers;
+
+    bool quit;
+    uint32_t curFrame;
+    uint32_t frameCount;
+    bool validate;
+    bool use_break;
+    bool suppress_popups;
+
+    uint32_t current_buffer;
+    uint32_t queue_family_count;
+};
+
+#if _WIN32
+// Include header required for parsing the command line options.
+#include <shellapi.h>
+
+Demo demo;
+
+// MS-Windows event handling function:
+LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+    switch (uMsg) {
+    case WM_CLOSE:
+        PostQuitMessage(validation_error);
+        break;
+    case WM_PAINT:
+        demo.run();
+        break;
+    case WM_GETMINMAXINFO: // set window's minimum size
+        ((MINMAXINFO *)lParam)->ptMinTrackSize = demo.minsize;
+        return 0;
+    case WM_SIZE:
+        // Resize the application to the new window size, except when
+        // it was minimized. Vulkan doesn't support images or swapchains
+        // with width=0 and height=0.
+        if (wParam != SIZE_MINIMIZED) {
+            demo.width = lParam & 0xffff;
+            demo.height = (lParam & 0xffff0000) >> 16;
+            demo.resize();
+        }
+        break;
+    default:
+        break;
+    }
+
+    return (DefWindowProc(hWnd, uMsg, wParam, lParam));
+}
+
+int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine,
+                   int nCmdShow) {
+    // TODO: Gah.. refactor. This isn't 1989.
+    MSG msg;   // message
+    bool done; // flag saying when app is complete
+    int argc;
+    char **argv;
+
+    // Use the CommandLine functions to get the command line arguments.
+    // Unfortunately, Microsoft outputs
+    // this information as wide characters for Unicode, and we simply want the
+    // Ascii version to be compatible
+    // with the non-Windows side.  So, we have to convert the information to
+    // Ascii character strings.
+    LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc);
+    if (nullptr == commandLineArgs) {
+        argc = 0;
+    }
+
+    if (argc > 0) {
+        argv = (char **)malloc(sizeof(char *) * argc);
+        if (argv == nullptr) {
+            argc = 0;
+        } else {
+            for (int iii = 0; iii < argc; iii++) {
+                size_t wideCharLen = wcslen(commandLineArgs[iii]);
+                size_t numConverted = 0;
+
+                argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1));
+                if (argv[iii] != nullptr) {
+                    wcstombs_s(&numConverted, argv[iii], wideCharLen + 1,
+                               commandLineArgs[iii], wideCharLen + 1);
+                }
+            }
+        }
+    } else {
+        argv = nullptr;
+    }
+
+    demo.init(argc, argv);
+
+    // Free up the items we had to allocate for the command line arguments.
+    if (argc > 0 && argv != nullptr) {
+        for (int iii = 0; iii < argc; iii++) {
+            if (argv[iii] != nullptr) {
+                free(argv[iii]);
+            }
+        }
+        free(argv);
+    }
+
+    demo.connection = hInstance;
+    strncpy(demo.name, "cube", APP_NAME_STR_LEN);
+    demo.create_window();
+    demo.init_vk_swapchain();
+
+    demo.prepare();
+
+    done = false; // initialize loop condition variable
+
+    // main message loop
+    while (!done) {
+        PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE);
+        if (msg.message == WM_QUIT) // check for a quit message
+        {
+            done = true; // if found, quit app
+        } else {
+            /* Translate and dispatch to event queue*/
+            TranslateMessage(&msg);
+            DispatchMessage(&msg);
+        }
+        RedrawWindow(demo.window, nullptr, nullptr, RDW_INTERNALPAINT);
+    }
+
+    demo.cleanup();
+
+    return (int)msg.wParam;
+}
+
+#elif __linux__
+
+#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
+static void handle_ping(void *data, wl_shell_surface *shell_surface,
+                        uint32_t serial) {
+    wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void handle_configure(void *data,
+                             wl_shell_surface *shell_surface,
+                             uint32_t edges, int32_t width,
+                             int32_t height) {}
+
+static void handle_popup_done(void *data,
+                              wl_shell_surface *shell_surface) {}
+
+static const wl_shell_surface_listener shell_surface_listener = {
+    handle_ping, handle_configure, handle_popup_done};
+#endif
+
+int main(int argc, char **argv) {
+    Demo demo;
+
+    demo.init(argc, argv);
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)
+    if (demo.use_xlib) {
+        demo.create_xlib_window();
+    } else {
+        demo.create_xcb_window();
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+    demo.create_xcb_window();
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+    demo.create_xlib_window();
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+    demo.create_window();
+#endif
+    }
+
+    demo.init_vk_swapchain();
+
+    demo.prepare();
+
+#if defined(VK_USE_PLATFORM_XLIB_KHR) && defined(VK_USE_PLATFORM_XCB_KHR)
+    if (demo.use_xlib) {
+        demo.run_xlib();
+    } else {
+        demo.run_xcb();
+#elif defined(VK_USE_PLATFORM_XCB_KHR)
+demo.run_xcb();
+#elif defined(VK_USE_PLATFORM_XLIB_KHR)
+demo.run_xlib();
+#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
+demo.run();
+#endif
+    }
+
+    demo.cleanup();
+
+    return validation_error;
+}
+
+#else
+#error "Platform not supported"
+#endif
diff --git a/demos/smoke/CMakeLists.txt b/demos/smoke/CMakeLists.txt
index 4dc90cd..756b648 100644
--- a/demos/smoke/CMakeLists.txt
+++ b/demos/smoke/CMakeLists.txt
@@ -2,8 +2,8 @@
 
 macro(generate_dispatch_table out)
     add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/${out}
-        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate-dispatch-table ${CMAKE_CURRENT_SOURCE_DIR}/${out}
-        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/generate-dispatch-table
+        COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/generate-dispatch-table.py ${CMAKE_CURRENT_SOURCE_DIR}/${out}
+        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/generate-dispatch-table.py
         )
 endmacro()
 
diff --git a/demos/smoke/android/build-and-install b/demos/smoke/android/build-and-install
index cbdaf0a..7ee17b4 100755
--- a/demos/smoke/android/build-and-install
+++ b/demos/smoke/android/build-and-install
@@ -2,13 +2,31 @@
 
 set -e
 
-SDK_DIR="$HOME/android/android-sdk-linux"
-NDK_DIR="$HOME/android/android-ndk-r10e"
+if [ -z "${ANDROID_SDK_HOME}" ];
+then echo "Please set ANDROID_SDK_HOME, exiting"; exit;
+else echo "ANDROID_SDK_HOME is ${ANDROID_SDK_HOME}";
+fi
+
+if [ -z "${ANDROID_NDK_HOME}" ];
+then echo "Please set ANDROID_NDK_HOME, exiting"; exit;
+else echo "ANDROID_NDK_HOME is ${ANDROID_NDK_HOME}";
+fi
+
 
 generate_local_properties() {
 	: > local.properties
-	echo "sdk.dir=${SDK_DIR}" >> local.properties
-	echo "ndk.dir=${NDK_DIR}" >> local.properties
+	echo "sdk.dir=${ANDROID_SDK_HOME}" >> local.properties
+	echo "ndk.dir=${ANDROID_NDK_HOME}" >> local.properties
+}
+
+glslang=$(realpath ../../../external/glslang/build/install/bin/glslangValidator)
+
+prebuild() {
+  ( cd ..; python3 generate-dispatch-table.py HelpersDispatchTable.h )
+  ( cd ..; python3 generate-dispatch-table.py HelpersDispatchTable.cpp )
+  ( cd ..; python3 glsl-to-spirv Smoke.frag Smoke.frag.h ${glslang} )
+  ( cd ..; python3 glsl-to-spirv Smoke.vert Smoke.vert.h ${glslang} )
+  ( cd ..; python3 glsl-to-spirv Smoke.push_constant.vert Smoke.push_constant.vert.h ${glslang} )
 }
 
 build() {
@@ -25,6 +43,7 @@
 }
 
 generate_local_properties
+prebuild
 build
 install
 #run
diff --git a/demos/smoke/android/build.gradle b/demos/smoke/android/build.gradle
index 9d6aba7..cb0e32b 100644
--- a/demos/smoke/android/build.gradle
+++ b/demos/smoke/android/build.gradle
@@ -4,14 +4,14 @@
     }
 
     dependencies {
-        classpath 'com.android.tools.build:gradle-experimental:0.6.0-alpha3'
+        classpath 'com.android.tools.build:gradle-experimental:0.8.0'
     }
 }
 
 apply plugin: 'com.android.model.application'
 
 def demosDir = "../.."
-def smokeDir = "${demosDir}/Smoke"
+def smokeDir = "${demosDir}/smoke"
 def glmDir = "${demosDir}/../libs"
 def vulkanDir = "${demosDir}/../include"
 
@@ -65,6 +65,7 @@
                     srcDir "${smokeDir}"
                     exclude 'ShellXcb.cpp'
                     exclude 'ShellWin32.cpp'
+                    exclude 'ShellWayland.cpp'
                 }
             }
         }
@@ -80,6 +81,7 @@
 
     android.productFlavors {
         create ("fat") {
+            ndk.abiFilters.add("arm64-v8a")
             ndk.abiFilters.add("armeabi-v7a")
             ndk.abiFilters.add("x86")
         }
diff --git a/demos/smoke/android/gradle/wrapper/gradle-wrapper.properties b/demos/smoke/android/gradle/wrapper/gradle-wrapper.properties
index 0fa1913..6c7451b 100644
--- a/demos/smoke/android/gradle/wrapper/gradle-wrapper.properties
+++ b/demos/smoke/android/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@
 distributionPath=wrapper/dists
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
diff --git a/demos/smoke/android/src/main/AndroidManifest.xml b/demos/smoke/android/src/main/AndroidManifest.xml
index c68af87..f6f98fb 100644
--- a/demos/smoke/android/src/main/AndroidManifest.xml
+++ b/demos/smoke/android/src/main/AndroidManifest.xml
@@ -2,6 +2,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.example.Smoke">
 
+        <!-- Permissions required for trace/replay of this app -->
+        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+        <uses-permission android:name="android.permission.INTERNET"/>
+
 	<application android:label="@string/app_name"
 		     android:hasCode="false"
 		     android:allowBackup="false">
diff --git a/demos/smoke/generate-dispatch-table b/demos/smoke/generate-dispatch-table.py
similarity index 99%
rename from demos/smoke/generate-dispatch-table
rename to demos/smoke/generate-dispatch-table.py
index 2158fa8..8ef9260 100755
--- a/demos/smoke/generate-dispatch-table
+++ b/demos/smoke/generate-dispatch-table.py
@@ -90,7 +90,7 @@
 
         return "\n".join(lines)
 
-# generated by "generate-dispatch-table parse vulkan.h"
+# generated by "generate-dispatch-table.py parse vulkan.h"
 vk_core = Extension(name='VK_core', version=0, guard=None, commands=[
     Command(name='CreateInstance', dispatch=None),
     Command(name='DestroyInstance', dispatch='VkInstance'),
diff --git a/demos/tri.c b/demos/tri.c
deleted file mode 100644
index adfef50..0000000
--- a/demos/tri.c
+++ /dev/null
@@ -1,2797 +0,0 @@
-/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 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: Chia-I Wu <olvaffe@gmail.com>
- * Author: Cody Northrop <cody@lunarg.com>
- * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
- * Author: Ian Elliott <ian@LunarG.com>
- * Author: Jon Ashburn <jon@lunarg.com>
- * Author: Piers Daniell <pdaniell@nvidia.com>
- * Author: Gwan-gyeong Mun <elongbug@gmail.com>
- */
-/*
- * Draw a textured triangle with depth testing.  This is written against Intel
- * ICD.  It does not do state transition nor object memory binding like it
- * should.  It also does no error checking.
- */
-
-#ifndef _MSC_VER
-#define _ISOC11_SOURCE /* for aligned_alloc() */
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <signal.h>
-
-#ifdef _WIN32
-#pragma comment(linker, "/subsystem:windows")
-#define APP_NAME_STR_LEN 80
-#endif // _WIN32
-
-#ifdef ANDROID
-#include "vulkan_wrapper.h"
-#else
-#include <vulkan/vulkan.h>
-#endif
-
-#define DEMO_TEXTURE_COUNT 1
-#define VERTEX_BUFFER_BIND_ID 0
-#define APP_SHORT_NAME "tri"
-#define APP_LONG_NAME "The Vulkan Triangle Demo Program"
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
-#if defined(NDEBUG) && defined(__GNUC__)
-#define U_ASSERT_ONLY __attribute__((unused))
-#else
-#define U_ASSERT_ONLY
-#endif
-
-#if defined(__GNUC__)
-#define UNUSED __attribute__((unused))
-#else
-#define UNUSED
-#endif
-
-#ifdef _WIN32
-#define ERR_EXIT(err_msg, err_class)                                           \
-    do {                                                                       \
-        if (!demo->suppress_popups)                                            \
-            MessageBox(NULL, err_msg, err_class, MB_OK);                       \
-        exit(1);                                                               \
-    } while (0)
-#elif defined __ANDROID__
-#include <android/log.h>
-#define ERR_EXIT(err_msg, err_class)                                           \
-    do {                                                                       \
-        ((void)__android_log_print(ANDROID_LOG_INFO, "Tri", err_msg));         \
-        exit(1);                                                               \
-    } while (0)
-#else
-#define ERR_EXIT(err_msg, err_class)                                           \
-    do {                                                                       \
-        printf(err_msg);                                                       \
-        fflush(stdout);                                                        \
-        exit(1);                                                               \
-    } while (0)
-#endif
-
-#define GET_INSTANCE_PROC_ADDR(inst, entrypoint)                               \
-    {                                                                          \
-        demo->fp##entrypoint =                                                 \
-            (PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
-        if (demo->fp##entrypoint == NULL) {                                    \
-            ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint,    \
-                     "vkGetInstanceProcAddr Failure");                         \
-        }                                                                      \
-    }
-
-#define GET_DEVICE_PROC_ADDR(dev, entrypoint)                                  \
-    {                                                                          \
-        demo->fp##entrypoint =                                                 \
-            (PFN_vk##entrypoint)vkGetDeviceProcAddr(dev, "vk" #entrypoint);    \
-        if (demo->fp##entrypoint == NULL) {                                    \
-            ERR_EXIT("vkGetDeviceProcAddr failed to find vk" #entrypoint,      \
-                     "vkGetDeviceProcAddr Failure");                           \
-        }                                                                      \
-    }
-
-struct texture_object {
-    VkSampler sampler;
-
-    VkImage image;
-    VkImageLayout imageLayout;
-
-    VkDeviceMemory mem;
-    VkImageView view;
-    int32_t tex_width, tex_height;
-};
-
-static int validation_error = 0;
-
-VKAPI_ATTR VkBool32 VKAPI_CALL
-BreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
-              uint64_t srcObject, size_t location, int32_t msgCode,
-              const char *pLayerPrefix, const char *pMsg,
-              void *pUserData) {
-#ifndef WIN32
-    raise(SIGTRAP);
-#else
-    DebugBreak();
-#endif
-
-    return false;
-}
-
-typedef struct {
-    VkImage image;
-    VkCommandBuffer cmd;
-    VkImageView view;
-} SwapchainBuffers;
-
-struct demo {
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-#define APP_NAME_STR_LEN 80
-    HINSTANCE connection;        // hInstance - Windows Instance
-    char name[APP_NAME_STR_LEN]; // Name to put on the window/icon
-    HWND window;                 // hWnd - window handle
-    POINT minsize;               // minimum window size
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
-    xcb_connection_t *connection;
-    xcb_screen_t *screen;
-    xcb_window_t window;
-    xcb_intern_atom_reply_t *atom_wm_delete_window;
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    struct wl_display *display;
-    struct wl_registry *registry;
-    struct wl_compositor *compositor;
-    struct wl_surface *window;
-    struct wl_shell *shell;
-    struct wl_shell_surface *shell_surface;
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-    ANativeWindow* window;
-#endif
-    VkSurfaceKHR surface;
-    bool prepared;
-    bool use_staging_buffer;
-    bool suppress_popups;
-
-    VkInstance inst;
-    VkPhysicalDevice gpu;
-    VkDevice device;
-    VkQueue queue;
-    VkPhysicalDeviceProperties gpu_props;
-    VkPhysicalDeviceFeatures gpu_features;
-    VkQueueFamilyProperties *queue_props;
-    uint32_t graphics_queue_node_index;
-
-    uint32_t enabled_extension_count;
-    uint32_t enabled_layer_count;
-    char *extension_names[64];
-    char *enabled_layers[64];
-
-    int width, height;
-    VkFormat format;
-    VkColorSpaceKHR color_space;
-
-    PFN_vkGetPhysicalDeviceSurfaceSupportKHR
-        fpGetPhysicalDeviceSurfaceSupportKHR;
-    PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR
-        fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
-    PFN_vkGetPhysicalDeviceSurfaceFormatsKHR
-        fpGetPhysicalDeviceSurfaceFormatsKHR;
-    PFN_vkGetPhysicalDeviceSurfacePresentModesKHR
-        fpGetPhysicalDeviceSurfacePresentModesKHR;
-    PFN_vkCreateSwapchainKHR fpCreateSwapchainKHR;
-    PFN_vkDestroySwapchainKHR fpDestroySwapchainKHR;
-    PFN_vkGetSwapchainImagesKHR fpGetSwapchainImagesKHR;
-    PFN_vkAcquireNextImageKHR fpAcquireNextImageKHR;
-    PFN_vkQueuePresentKHR fpQueuePresentKHR;
-    uint32_t swapchainImageCount;
-    VkSwapchainKHR swapchain;
-    SwapchainBuffers *buffers;
-
-    VkCommandPool cmd_pool;
-
-    struct {
-        VkFormat format;
-
-        VkImage image;
-        VkDeviceMemory mem;
-        VkImageView view;
-    } depth;
-
-    struct texture_object textures[DEMO_TEXTURE_COUNT];
-
-    struct {
-        VkBuffer buf;
-        VkDeviceMemory mem;
-
-        VkPipelineVertexInputStateCreateInfo vi;
-        VkVertexInputBindingDescription vi_bindings[1];
-        VkVertexInputAttributeDescription vi_attrs[2];
-    } vertices;
-
-    VkCommandBuffer setup_cmd; // Command Buffer for initialization commands
-    VkCommandBuffer draw_cmd;  // Command Buffer for drawing commands
-    VkPipelineLayout pipeline_layout;
-    VkDescriptorSetLayout desc_layout;
-    VkPipelineCache pipelineCache;
-    VkRenderPass render_pass;
-    VkPipeline pipeline;
-
-    VkShaderModule vert_shader_module;
-    VkShaderModule frag_shader_module;
-
-    VkDescriptorPool desc_pool;
-    VkDescriptorSet desc_set;
-
-    VkFramebuffer *framebuffers;
-
-    VkPhysicalDeviceMemoryProperties memory_properties;
-
-    int32_t curFrame;
-    int32_t frameCount;
-    bool validate;
-    bool use_break;
-    PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallback;
-    PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallback;
-    VkDebugReportCallbackEXT msg_callback;
-    PFN_vkDebugReportMessageEXT DebugReportMessage;
-
-    float depthStencil;
-    float depthIncrement;
-
-    bool quit;
-    uint32_t current_buffer;
-    uint32_t queue_count;
-};
-
-VKAPI_ATTR VkBool32 VKAPI_CALL
-dbgFunc(VkFlags msgFlags, VkDebugReportObjectTypeEXT objType,
-    uint64_t srcObject, size_t location, int32_t msgCode,
-    const char *pLayerPrefix, const char *pMsg, void *pUserData) {
-    char *message = (char *)malloc(strlen(pMsg) + 100);
-
-    assert(message);
-
-    validation_error = 1;
-
-    if (msgFlags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
-        sprintf(message, "ERROR: [%s] Code %d : %s", pLayerPrefix, msgCode,
-            pMsg);
-    } else if (msgFlags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
-        sprintf(message, "WARNING: [%s] Code %d : %s", pLayerPrefix, msgCode,
-            pMsg);
-    } else {
-        return false;
-    }
-
-#ifdef _WIN32
-    struct demo *demo = (struct demo*) pUserData;
-    if (!demo->suppress_popups)
-        MessageBox(NULL, message, "Alert", MB_OK);
-#else
-    printf("%s\n", message);
-    fflush(stdout);
-#endif
-    free(message);
-
-    /*
-    * false indicates that layer should not bail-out of an
-    * API call that had validation failures. This may mean that the
-    * app dies inside the driver due to invalid parameter(s).
-    * That's what would happen without validation layers, so we'll
-    * keep that behavior here.
-    */
-    return false;
-}
-
-// Forward declaration:
-static void demo_resize(struct demo *demo);
-
-static bool memory_type_from_properties(struct demo *demo, uint32_t typeBits,
-                                        VkFlags requirements_mask,
-                                        uint32_t *typeIndex) {
-    // Search memtypes to find first index with those properties
-    for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; i++) {
-        if ((typeBits & 1) == 1) {
-            // Type is available, does it match user properties?
-            if ((demo->memory_properties.memoryTypes[i].propertyFlags &
-                 requirements_mask) == requirements_mask) {
-                *typeIndex = i;
-                return true;
-            }
-        }
-        typeBits >>= 1;
-    }
-    // No memory types matched, return failure
-    return false;
-}
-
-static void demo_flush_init_cmd(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-
-    if (demo->setup_cmd == VK_NULL_HANDLE)
-        return;
-
-    err = vkEndCommandBuffer(demo->setup_cmd);
-    assert(!err);
-
-    const VkCommandBuffer cmd_bufs[] = {demo->setup_cmd};
-    VkFence nullFence = {VK_NULL_HANDLE};
-    VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-                                .pNext = NULL,
-                                .waitSemaphoreCount = 0,
-                                .pWaitSemaphores = NULL,
-                                .pWaitDstStageMask = NULL,
-                                .commandBufferCount = 1,
-                                .pCommandBuffers = cmd_bufs,
-                                .signalSemaphoreCount = 0,
-                                .pSignalSemaphores = NULL};
-
-    err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence);
-    assert(!err);
-
-    err = vkQueueWaitIdle(demo->queue);
-    assert(!err);
-
-    vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, cmd_bufs);
-    demo->setup_cmd = VK_NULL_HANDLE;
-}
-
-static void demo_set_image_layout(struct demo *demo, VkImage image,
-                                  VkImageAspectFlags aspectMask,
-                                  VkImageLayout old_image_layout,
-                                  VkImageLayout new_image_layout,
-                                  VkAccessFlagBits srcAccessMask) {
-
-    VkResult U_ASSERT_ONLY err;
-
-    if (demo->setup_cmd == VK_NULL_HANDLE) {
-        const VkCommandBufferAllocateInfo cmd = {
-            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
-            .pNext = NULL,
-            .commandPool = demo->cmd_pool,
-            .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
-            .commandBufferCount = 1,
-        };
-
-        err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->setup_cmd);
-        assert(!err);
-
-        VkCommandBufferBeginInfo cmd_buf_info = {
-            .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-            .pNext = NULL,
-            .flags = 0,
-            .pInheritanceInfo = NULL,
-        };
-        err = vkBeginCommandBuffer(demo->setup_cmd, &cmd_buf_info);
-        assert(!err);
-    }
-
-    VkImageMemoryBarrier image_memory_barrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-        .srcAccessMask = srcAccessMask,
-        .dstAccessMask = 0,
-        .oldLayout = old_image_layout,
-        .newLayout = new_image_layout,
-        .image = image,
-        .subresourceRange = {aspectMask, 0, 1, 0, 1}};
-
-    if (new_image_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
-        /* Make sure anything that was copying from this image has completed */
-        image_memory_barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
-    }
-
-    if (new_image_layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
-        image_memory_barrier.dstAccessMask =
-            VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
-    }
-
-    if (new_image_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
-        image_memory_barrier.dstAccessMask =
-            VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    }
-
-    if (new_image_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
-        /* Make sure any Copy or CPU writes to image are flushed */
-        image_memory_barrier.dstAccessMask =
-            VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT;
-    }
-
-    VkImageMemoryBarrier *pmemory_barrier = &image_memory_barrier;
-
-    VkPipelineStageFlags src_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-    VkPipelineStageFlags dest_stages = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
-
-    vkCmdPipelineBarrier(demo->setup_cmd, src_stages, dest_stages, 0, 0, NULL,
-                         0, NULL, 1, pmemory_barrier);
-}
-
-static void demo_draw_build_cmd(struct demo *demo) {
-    const VkCommandBufferBeginInfo cmd_buf_info = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-        .pNext = NULL,
-        .flags = 0,
-        .pInheritanceInfo = NULL,
-    };
-    const VkClearValue clear_values[2] = {
-            [0] = {.color.float32 = {0.2f, 0.2f, 0.2f, 0.2f}},
-            [1] = {.depthStencil = {demo->depthStencil, 0}},
-    };
-    const VkRenderPassBeginInfo rp_begin = {
-        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-        .pNext = NULL,
-        .renderPass = demo->render_pass,
-        .framebuffer = demo->framebuffers[demo->current_buffer],
-        .renderArea.offset.x = 0,
-        .renderArea.offset.y = 0,
-        .renderArea.extent.width = demo->width,
-        .renderArea.extent.height = demo->height,
-        .clearValueCount = 2,
-        .pClearValues = clear_values,
-    };
-    VkResult U_ASSERT_ONLY err;
-
-    err = vkBeginCommandBuffer(demo->draw_cmd, &cmd_buf_info);
-    assert(!err);
-
-    // We can use LAYOUT_UNDEFINED as a wildcard here because we don't care what
-    // happens to the previous contents of the image
-    VkImageMemoryBarrier image_memory_barrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-        .srcAccessMask = 0,
-        .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-        .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
-        .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .image = demo->buffers[demo->current_buffer].image,
-        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
-
-    vkCmdPipelineBarrier(demo->draw_cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0,
-                         NULL, 1, &image_memory_barrier);
-    vkCmdBeginRenderPass(demo->draw_cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
-    vkCmdBindPipeline(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-                      demo->pipeline);
-    vkCmdBindDescriptorSets(demo->draw_cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-                            demo->pipeline_layout, 0, 1, &demo->desc_set, 0,
-                            NULL);
-
-    VkViewport viewport;
-    memset(&viewport, 0, sizeof(viewport));
-    viewport.height = (float)demo->height;
-    viewport.width = (float)demo->width;
-    viewport.minDepth = (float)0.0f;
-    viewport.maxDepth = (float)1.0f;
-    vkCmdSetViewport(demo->draw_cmd, 0, 1, &viewport);
-
-    VkRect2D scissor;
-    memset(&scissor, 0, sizeof(scissor));
-    scissor.extent.width = demo->width;
-    scissor.extent.height = demo->height;
-    scissor.offset.x = 0;
-    scissor.offset.y = 0;
-    vkCmdSetScissor(demo->draw_cmd, 0, 1, &scissor);
-
-    VkDeviceSize offsets[1] = {0};
-    vkCmdBindVertexBuffers(demo->draw_cmd, VERTEX_BUFFER_BIND_ID, 1,
-                           &demo->vertices.buf, offsets);
-
-    vkCmdDraw(demo->draw_cmd, 3, 1, 0, 0);
-    vkCmdEndRenderPass(demo->draw_cmd);
-
-    VkImageMemoryBarrier prePresentBarrier = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-        .pNext = NULL,
-        .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-        .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
-        .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-        .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
-        .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
-        .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
-
-    prePresentBarrier.image = demo->buffers[demo->current_buffer].image;
-    VkImageMemoryBarrier *pmemory_barrier = &prePresentBarrier;
-    vkCmdPipelineBarrier(demo->draw_cmd, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
-                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, NULL, 0,
-                         NULL, 1, pmemory_barrier);
-
-    err = vkEndCommandBuffer(demo->draw_cmd);
-    assert(!err);
-}
-
-static void demo_draw(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-    VkSemaphore imageAcquiredSemaphore, drawCompleteSemaphore;
-    VkSemaphoreCreateInfo semaphoreCreateInfo = {
-        .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
-        .pNext = NULL,
-        .flags = 0,
-    };
-
-    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo,
-                            NULL, &imageAcquiredSemaphore);
-    assert(!err);
-
-    err = vkCreateSemaphore(demo->device, &semaphoreCreateInfo,
-                            NULL, &drawCompleteSemaphore);
-    assert(!err);
-
-    // Get the index of the next available swapchain image:
-    err = demo->fpAcquireNextImageKHR(demo->device, demo->swapchain, UINT64_MAX,
-                                      imageAcquiredSemaphore,
-                                      (VkFence)0, // TODO: Show use of fence
-                                      &demo->current_buffer);
-    if (err == VK_ERROR_OUT_OF_DATE_KHR) {
-        // demo->swapchain is out of date (e.g. the window was resized) and
-        // must be recreated:
-        demo_resize(demo);
-        demo_draw(demo);
-        vkDestroySemaphore(demo->device, imageAcquiredSemaphore, NULL);
-        vkDestroySemaphore(demo->device, drawCompleteSemaphore, NULL);
-        return;
-    } else if (err == VK_SUBOPTIMAL_KHR) {
-        // demo->swapchain is not as optimal as it could be, but the platform's
-        // presentation engine will still present the image correctly.
-    } else {
-        assert(!err);
-    }
-
-    demo_flush_init_cmd(demo);
-
-    // Wait for the present complete semaphore to be signaled to ensure
-    // that the image won't be rendered to until the presentation
-    // engine has fully released ownership to the application, and it is
-    // okay to render to the image.
-
-    demo_draw_build_cmd(demo);
-    VkFence nullFence = VK_NULL_HANDLE;
-    VkPipelineStageFlags pipe_stage_flags =
-        VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
-    VkSubmitInfo submit_info = {.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-                                .pNext = NULL,
-                                .waitSemaphoreCount = 1,
-                                .pWaitSemaphores = &imageAcquiredSemaphore,
-                                .pWaitDstStageMask = &pipe_stage_flags,
-                                .commandBufferCount = 1,
-                                .pCommandBuffers = &demo->draw_cmd,
-                                .signalSemaphoreCount = 1,
-                                .pSignalSemaphores = &drawCompleteSemaphore};
-
-    err = vkQueueSubmit(demo->queue, 1, &submit_info, nullFence);
-    assert(!err);
-
-    VkPresentInfoKHR present = {
-        .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
-        .pNext = NULL,
-        .waitSemaphoreCount = 1,
-        .pWaitSemaphores = &drawCompleteSemaphore,
-        .swapchainCount = 1,
-        .pSwapchains = &demo->swapchain,
-        .pImageIndices = &demo->current_buffer,
-    };
-
-    err = demo->fpQueuePresentKHR(demo->queue, &present);
-    if (err == VK_ERROR_OUT_OF_DATE_KHR) {
-        // demo->swapchain is out of date (e.g. the window was resized) and
-        // must be recreated:
-        demo_resize(demo);
-    } else if (err == VK_SUBOPTIMAL_KHR) {
-        // demo->swapchain is not as optimal as it could be, but the platform's
-        // presentation engine will still present the image correctly.
-    } else {
-        assert(!err);
-    }
-
-    err = vkQueueWaitIdle(demo->queue);
-    assert(err == VK_SUCCESS);
-
-    vkDestroySemaphore(demo->device, imageAcquiredSemaphore, NULL);
-    vkDestroySemaphore(demo->device, drawCompleteSemaphore, NULL);
-}
-
-static void demo_prepare_buffers(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-    VkSwapchainKHR oldSwapchain = demo->swapchain;
-
-    // Check the surface capabilities and formats
-    VkSurfaceCapabilitiesKHR surfCapabilities;
-    err = demo->fpGetPhysicalDeviceSurfaceCapabilitiesKHR(
-        demo->gpu, demo->surface, &surfCapabilities);
-    assert(!err);
-
-    uint32_t presentModeCount;
-    err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR(
-        demo->gpu, demo->surface, &presentModeCount, NULL);
-    assert(!err);
-    VkPresentModeKHR *presentModes =
-        (VkPresentModeKHR *)malloc(presentModeCount * sizeof(VkPresentModeKHR));
-    assert(presentModes);
-    err = demo->fpGetPhysicalDeviceSurfacePresentModesKHR(
-        demo->gpu, demo->surface, &presentModeCount, presentModes);
-    assert(!err);
-
-    VkExtent2D swapchainExtent;
-    // width and height are either both 0xFFFFFFFF, or both not 0xFFFFFFFF.
-    if (surfCapabilities.currentExtent.width == 0xFFFFFFFF) {
-        // If the surface size is undefined, the size is set to the size
-        // of the images requested, which must fit within the minimum and
-        // maximum values.
-        swapchainExtent.width = demo->width;
-        swapchainExtent.height = demo->height;
-
-        if (swapchainExtent.width < surfCapabilities.minImageExtent.width) {
-            swapchainExtent.width = surfCapabilities.minImageExtent.width;
-        } else if (swapchainExtent.width > surfCapabilities.maxImageExtent.width) {
-            swapchainExtent.width = surfCapabilities.maxImageExtent.width;
-        }
-        
-        if (swapchainExtent.height < surfCapabilities.minImageExtent.height) {
-            swapchainExtent.height = surfCapabilities.minImageExtent.height;
-        } else if (swapchainExtent.height > surfCapabilities.maxImageExtent.height) {
-            swapchainExtent.height = surfCapabilities.maxImageExtent.height;
-        }
-    } else {
-        // If the surface size is defined, the swap chain size must match
-        swapchainExtent = surfCapabilities.currentExtent;
-        demo->width = surfCapabilities.currentExtent.width;
-        demo->height = surfCapabilities.currentExtent.height;
-    }
-
-    VkPresentModeKHR swapchainPresentMode = VK_PRESENT_MODE_FIFO_KHR;
-
-    // Determine the number of VkImage's to use in the swap chain.
-    // Application desires to only acquire 1 image at a time (which is
-    // "surfCapabilities.minImageCount").
-    uint32_t desiredNumOfSwapchainImages = surfCapabilities.minImageCount;
-    // If maxImageCount is 0, we can ask for as many images as we want;
-    // otherwise we're limited to maxImageCount
-    if ((surfCapabilities.maxImageCount > 0) &&
-        (desiredNumOfSwapchainImages > surfCapabilities.maxImageCount)) {
-        // Application must settle for fewer images than desired:
-        desiredNumOfSwapchainImages = surfCapabilities.maxImageCount;
-    }
-
-    VkSurfaceTransformFlagsKHR preTransform;
-    if (surfCapabilities.supportedTransforms &
-        VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) {
-        preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
-    } else {
-        preTransform = surfCapabilities.currentTransform;
-    }
-
-    const VkSwapchainCreateInfoKHR swapchain = {
-        .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
-        .pNext = NULL,
-        .surface = demo->surface,
-        .minImageCount = desiredNumOfSwapchainImages,
-        .imageFormat = demo->format,
-        .imageColorSpace = demo->color_space,
-        .imageExtent =
-            {
-             .width = swapchainExtent.width, .height = swapchainExtent.height,
-            },
-        .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
-        .preTransform = preTransform,
-        .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
-        .imageArrayLayers = 1,
-        .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE,
-        .queueFamilyIndexCount = 0,
-        .pQueueFamilyIndices = NULL,
-        .presentMode = swapchainPresentMode,
-        .oldSwapchain = oldSwapchain,
-        .clipped = true,
-    };
-    uint32_t i;
-
-    err = demo->fpCreateSwapchainKHR(demo->device, &swapchain, NULL,
-                                     &demo->swapchain);
-    assert(!err);
-
-    // If we just re-created an existing swapchain, we should destroy the old
-    // swapchain at this point.
-    // Note: destroying the swapchain also cleans up all its associated
-    // presentable images once the platform is done with them.
-    if (oldSwapchain != VK_NULL_HANDLE) {
-        demo->fpDestroySwapchainKHR(demo->device, oldSwapchain, NULL);
-    }
-
-    err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain,
-                                        &demo->swapchainImageCount, NULL);
-    assert(!err);
-
-    VkImage *swapchainImages =
-        (VkImage *)malloc(demo->swapchainImageCount * sizeof(VkImage));
-    assert(swapchainImages);
-    err = demo->fpGetSwapchainImagesKHR(demo->device, demo->swapchain,
-                                        &demo->swapchainImageCount,
-                                        swapchainImages);
-    assert(!err);
-
-    demo->buffers = (SwapchainBuffers *)malloc(sizeof(SwapchainBuffers) *
-                                               demo->swapchainImageCount);
-    assert(demo->buffers);
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        VkImageViewCreateInfo color_attachment_view = {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .pNext = NULL,
-            .format = demo->format,
-            .components =
-                {
-                 .r = VK_COMPONENT_SWIZZLE_R,
-                 .g = VK_COMPONENT_SWIZZLE_G,
-                 .b = VK_COMPONENT_SWIZZLE_B,
-                 .a = VK_COMPONENT_SWIZZLE_A,
-                },
-            .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-                                 .baseMipLevel = 0,
-                                 .levelCount = 1,
-                                 .baseArrayLayer = 0,
-                                 .layerCount = 1},
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .flags = 0,
-        };
-
-        demo->buffers[i].image = swapchainImages[i];
-
-        color_attachment_view.image = demo->buffers[i].image;
-
-        err = vkCreateImageView(demo->device, &color_attachment_view, NULL,
-                                &demo->buffers[i].view);
-        assert(!err);
-    }
-
-    demo->current_buffer = 0;
-
-    if (NULL != presentModes) {
-        free(presentModes);
-    }
-}
-
-static void demo_prepare_depth(struct demo *demo) {
-    const VkFormat depth_format = VK_FORMAT_D16_UNORM;
-    const VkImageCreateInfo image = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-        .pNext = NULL,
-        .imageType = VK_IMAGE_TYPE_2D,
-        .format = depth_format,
-        .extent = {demo->width, demo->height, 1},
-        .mipLevels = 1,
-        .arrayLayers = 1,
-        .samples = VK_SAMPLE_COUNT_1_BIT,
-        .tiling = VK_IMAGE_TILING_OPTIMAL,
-        .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
-        .flags = 0,
-    };
-    VkMemoryAllocateInfo mem_alloc = {
-        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
-        .pNext = NULL,
-        .allocationSize = 0,
-        .memoryTypeIndex = 0,
-    };
-    VkImageViewCreateInfo view = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-        .pNext = NULL,
-        .image = VK_NULL_HANDLE,
-        .format = depth_format,
-        .subresourceRange = {.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT,
-                             .baseMipLevel = 0,
-                             .levelCount = 1,
-                             .baseArrayLayer = 0,
-                             .layerCount = 1},
-        .flags = 0,
-        .viewType = VK_IMAGE_VIEW_TYPE_2D,
-    };
-
-    VkMemoryRequirements mem_reqs;
-    VkResult U_ASSERT_ONLY err;
-    bool U_ASSERT_ONLY pass;
-
-    demo->depth.format = depth_format;
-
-    /* create image */
-    err = vkCreateImage(demo->device, &image, NULL, &demo->depth.image);
-    assert(!err);
-
-    /* get memory requirements for this object */
-    vkGetImageMemoryRequirements(demo->device, demo->depth.image, &mem_reqs);
-
-    /* select memory size and type */
-    mem_alloc.allocationSize = mem_reqs.size;
-    pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits,
-                                       0, /* No requirements */
-                                       &mem_alloc.memoryTypeIndex);
-    assert(pass);
-
-    /* allocate memory */
-    err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->depth.mem);
-    assert(!err);
-
-    /* bind memory */
-    err =
-        vkBindImageMemory(demo->device, demo->depth.image, demo->depth.mem, 0);
-    assert(!err);
-
-    demo_set_image_layout(demo, demo->depth.image, VK_IMAGE_ASPECT_DEPTH_BIT,
-                          VK_IMAGE_LAYOUT_UNDEFINED,
-                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                          0);
-
-    /* create image view */
-    view.image = demo->depth.image;
-    err = vkCreateImageView(demo->device, &view, NULL, &demo->depth.view);
-    assert(!err);
-}
-
-static void
-demo_prepare_texture_image(struct demo *demo, const uint32_t *tex_colors,
-                           struct texture_object *tex_obj, VkImageTiling tiling,
-                           VkImageUsageFlags usage, VkFlags required_props) {
-    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
-    const int32_t tex_width = 2;
-    const int32_t tex_height = 2;
-    VkResult U_ASSERT_ONLY err;
-    bool U_ASSERT_ONLY pass;
-
-    tex_obj->tex_width = tex_width;
-    tex_obj->tex_height = tex_height;
-
-    const VkImageCreateInfo image_create_info = {
-        .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-        .pNext = NULL,
-        .imageType = VK_IMAGE_TYPE_2D,
-        .format = tex_format,
-        .extent = {tex_width, tex_height, 1},
-        .mipLevels = 1,
-        .arrayLayers = 1,
-        .samples = VK_SAMPLE_COUNT_1_BIT,
-        .tiling = tiling,
-        .usage = usage,
-        .flags = 0,
-        .initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED
-    };
-    VkMemoryAllocateInfo mem_alloc = {
-        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
-        .pNext = NULL,
-        .allocationSize = 0,
-        .memoryTypeIndex = 0,
-    };
-
-    VkMemoryRequirements mem_reqs;
-
-    err =
-        vkCreateImage(demo->device, &image_create_info, NULL, &tex_obj->image);
-    assert(!err);
-
-    vkGetImageMemoryRequirements(demo->device, tex_obj->image, &mem_reqs);
-
-    mem_alloc.allocationSize = mem_reqs.size;
-    pass =
-        memory_type_from_properties(demo, mem_reqs.memoryTypeBits,
-                                    required_props, &mem_alloc.memoryTypeIndex);
-    assert(pass);
-
-    /* allocate memory */
-    err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &tex_obj->mem);
-    assert(!err);
-
-    /* bind memory */
-    err = vkBindImageMemory(demo->device, tex_obj->image, tex_obj->mem, 0);
-    assert(!err);
-
-    if (required_props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
-        const VkImageSubresource subres = {
-            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
-            .mipLevel = 0,
-            .arrayLayer = 0,
-        };
-        VkSubresourceLayout layout;
-        void *data;
-        int32_t x, y;
-
-        vkGetImageSubresourceLayout(demo->device, tex_obj->image, &subres,
-                                    &layout);
-
-        err = vkMapMemory(demo->device, tex_obj->mem, 0,
-                          mem_alloc.allocationSize, 0, &data);
-        assert(!err);
-
-        for (y = 0; y < tex_height; y++) {
-            uint32_t *row = (uint32_t *)((char *)data + layout.rowPitch * y);
-            for (x = 0; x < tex_width; x++)
-                row[x] = tex_colors[(x & 1) ^ (y & 1)];
-        }
-
-        vkUnmapMemory(demo->device, tex_obj->mem);
-    }
-
-    tex_obj->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-    demo_set_image_layout(demo, tex_obj->image, VK_IMAGE_ASPECT_COLOR_BIT,
-                          VK_IMAGE_LAYOUT_PREINITIALIZED, tex_obj->imageLayout,
-                          VK_ACCESS_HOST_WRITE_BIT);
-    /* setting the image layout does not reference the actual memory so no need
-     * to add a mem ref */
-}
-
-static void demo_destroy_texture_image(struct demo *demo,
-                                       struct texture_object *tex_obj) {
-    /* clean up staging resources */
-    vkDestroyImage(demo->device, tex_obj->image, NULL);
-    vkFreeMemory(demo->device, tex_obj->mem, NULL);
-}
-
-static void demo_prepare_textures(struct demo *demo) {
-    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
-    VkFormatProperties props;
-    const uint32_t tex_colors[DEMO_TEXTURE_COUNT][2] = {
-        {0xffff0000, 0xff00ff00},
-    };
-    uint32_t i;
-    VkResult U_ASSERT_ONLY err;
-
-    vkGetPhysicalDeviceFormatProperties(demo->gpu, tex_format, &props);
-
-    for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
-        if ((props.linearTilingFeatures &
-             VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) &&
-            !demo->use_staging_buffer) {
-            /* Device can texture using linear textures */
-            demo_prepare_texture_image(
-                demo, tex_colors[i], &demo->textures[i], VK_IMAGE_TILING_LINEAR,
-                VK_IMAGE_USAGE_SAMPLED_BIT,
-                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-        } else if (props.optimalTilingFeatures &
-                   VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) {
-            /* Must use staging buffer to copy linear texture to optimized */
-            struct texture_object staging_texture;
-
-            memset(&staging_texture, 0, sizeof(staging_texture));
-            demo_prepare_texture_image(
-                demo, tex_colors[i], &staging_texture, VK_IMAGE_TILING_LINEAR,
-                VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
-                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                    VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
-            demo_prepare_texture_image(
-                demo, tex_colors[i], &demo->textures[i],
-                VK_IMAGE_TILING_OPTIMAL,
-                (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT),
-                VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-
-            demo_set_image_layout(demo, staging_texture.image,
-                                  VK_IMAGE_ASPECT_COLOR_BIT,
-                                  staging_texture.imageLayout,
-                                  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                                  0);
-
-            demo_set_image_layout(demo, demo->textures[i].image,
-                                  VK_IMAGE_ASPECT_COLOR_BIT,
-                                  demo->textures[i].imageLayout,
-                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                  0);
-
-            VkImageCopy copy_region = {
-                .srcSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
-                .srcOffset = {0, 0, 0},
-                .dstSubresource = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1},
-                .dstOffset = {0, 0, 0},
-                .extent = {staging_texture.tex_width,
-                           staging_texture.tex_height, 1},
-            };
-            vkCmdCopyImage(
-                demo->setup_cmd, staging_texture.image,
-                VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, demo->textures[i].image,
-                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy_region);
-
-            demo_set_image_layout(demo, demo->textures[i].image,
-                                  VK_IMAGE_ASPECT_COLOR_BIT,
-                                  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                                  demo->textures[i].imageLayout,
-                                  0);
-
-            demo_flush_init_cmd(demo);
-
-            demo_destroy_texture_image(demo, &staging_texture);
-        } else {
-            /* Can't support VK_FORMAT_B8G8R8A8_UNORM !? */
-            assert(!"No support for B8G8R8A8_UNORM as texture image format");
-        }
-
-        const VkSamplerCreateInfo sampler = {
-            .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
-            .pNext = NULL,
-            .magFilter = VK_FILTER_NEAREST,
-            .minFilter = VK_FILTER_NEAREST,
-            .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
-            .addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT,
-            .addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT,
-            .addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT,
-            .mipLodBias = 0.0f,
-            .anisotropyEnable = VK_FALSE,
-            .maxAnisotropy = 1,
-            .compareOp = VK_COMPARE_OP_NEVER,
-            .minLod = 0.0f,
-            .maxLod = 0.0f,
-            .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
-            .unnormalizedCoordinates = VK_FALSE,
-        };
-        VkImageViewCreateInfo view = {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .pNext = NULL,
-            .image = VK_NULL_HANDLE,
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .format = tex_format,
-            .components =
-                {
-                 VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
-                 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A,
-                },
-            .subresourceRange = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
-            .flags = 0,
-        };
-
-        /* create sampler */
-        err = vkCreateSampler(demo->device, &sampler, NULL,
-                              &demo->textures[i].sampler);
-        assert(!err);
-
-        /* create image view */
-        view.image = demo->textures[i].image;
-        err = vkCreateImageView(demo->device, &view, NULL,
-                                &demo->textures[i].view);
-        assert(!err);
-    }
-}
-
-static void demo_prepare_vertices(struct demo *demo) {
-    // clang-format off
-    const float vb[3][5] = {
-        /*      position             texcoord */
-        { -1.0f, -1.0f,  0.25f,     0.0f, 0.0f },
-        {  1.0f, -1.0f,  0.25f,     1.0f, 0.0f },
-        {  0.0f,  1.0f,  1.0f,      0.5f, 1.0f },
-    };
-    // clang-format on
-    const VkBufferCreateInfo buf_info = {
-        .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
-        .pNext = NULL,
-        .size = sizeof(vb),
-        .usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
-        .flags = 0,
-    };
-    VkMemoryAllocateInfo mem_alloc = {
-        .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
-        .pNext = NULL,
-        .allocationSize = 0,
-        .memoryTypeIndex = 0,
-    };
-    VkMemoryRequirements mem_reqs;
-    VkResult U_ASSERT_ONLY err;
-    bool U_ASSERT_ONLY pass;
-    void *data;
-
-    memset(&demo->vertices, 0, sizeof(demo->vertices));
-
-    err = vkCreateBuffer(demo->device, &buf_info, NULL, &demo->vertices.buf);
-    assert(!err);
-
-    vkGetBufferMemoryRequirements(demo->device, demo->vertices.buf, &mem_reqs);
-    assert(!err);
-
-    mem_alloc.allocationSize = mem_reqs.size;
-    pass = memory_type_from_properties(demo, mem_reqs.memoryTypeBits,
-                                       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
-                                           VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
-                                       &mem_alloc.memoryTypeIndex);
-    assert(pass);
-
-    err = vkAllocateMemory(demo->device, &mem_alloc, NULL, &demo->vertices.mem);
-    assert(!err);
-
-    err = vkMapMemory(demo->device, demo->vertices.mem, 0,
-                      mem_alloc.allocationSize, 0, &data);
-    assert(!err);
-
-    memcpy(data, vb, sizeof(vb));
-
-    vkUnmapMemory(demo->device, demo->vertices.mem);
-
-    err = vkBindBufferMemory(demo->device, demo->vertices.buf,
-                             demo->vertices.mem, 0);
-    assert(!err);
-
-    demo->vertices.vi.sType =
-        VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
-    demo->vertices.vi.pNext = NULL;
-    demo->vertices.vi.vertexBindingDescriptionCount = 1;
-    demo->vertices.vi.pVertexBindingDescriptions = demo->vertices.vi_bindings;
-    demo->vertices.vi.vertexAttributeDescriptionCount = 2;
-    demo->vertices.vi.pVertexAttributeDescriptions = demo->vertices.vi_attrs;
-
-    demo->vertices.vi_bindings[0].binding = VERTEX_BUFFER_BIND_ID;
-    demo->vertices.vi_bindings[0].stride = sizeof(vb[0]);
-    demo->vertices.vi_bindings[0].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
-
-    demo->vertices.vi_attrs[0].binding = VERTEX_BUFFER_BIND_ID;
-    demo->vertices.vi_attrs[0].location = 0;
-    demo->vertices.vi_attrs[0].format = VK_FORMAT_R32G32B32_SFLOAT;
-    demo->vertices.vi_attrs[0].offset = 0;
-
-    demo->vertices.vi_attrs[1].binding = VERTEX_BUFFER_BIND_ID;
-    demo->vertices.vi_attrs[1].location = 1;
-    demo->vertices.vi_attrs[1].format = VK_FORMAT_R32G32_SFLOAT;
-    demo->vertices.vi_attrs[1].offset = sizeof(float) * 3;
-}
-
-static void demo_prepare_descriptor_layout(struct demo *demo) {
-    const VkDescriptorSetLayoutBinding layout_binding = {
-        .binding = 0,
-        .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-        .descriptorCount = DEMO_TEXTURE_COUNT,
-        .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
-        .pImmutableSamplers = NULL,
-    };
-    const VkDescriptorSetLayoutCreateInfo descriptor_layout = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-        .pNext = NULL,
-        .bindingCount = 1,
-        .pBindings = &layout_binding,
-    };
-    VkResult U_ASSERT_ONLY err;
-
-    err = vkCreateDescriptorSetLayout(demo->device, &descriptor_layout, NULL,
-                                      &demo->desc_layout);
-    assert(!err);
-
-    const VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = {
-        .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-        .pNext = NULL,
-        .setLayoutCount = 1,
-        .pSetLayouts = &demo->desc_layout,
-    };
-
-    err = vkCreatePipelineLayout(demo->device, &pPipelineLayoutCreateInfo, NULL,
-                                 &demo->pipeline_layout);
-    assert(!err);
-}
-
-static void demo_prepare_render_pass(struct demo *demo) {
-    const VkAttachmentDescription attachments[2] = {
-            [0] =
-                {
-                 .format = demo->format,
-                 .samples = VK_SAMPLE_COUNT_1_BIT,
-                 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
-                 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
-                 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                 .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                 .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                },
-            [1] =
-                {
-                 .format = demo->depth.format,
-                 .samples = VK_SAMPLE_COUNT_1_BIT,
-                 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
-                 .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                 .initialLayout =
-                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                 .finalLayout =
-                     VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                },
-    };
-    const VkAttachmentReference color_reference = {
-        .attachment = 0, .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-    };
-    const VkAttachmentReference depth_reference = {
-        .attachment = 1,
-        .layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-    };
-    const VkSubpassDescription subpass = {
-        .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
-        .flags = 0,
-        .inputAttachmentCount = 0,
-        .pInputAttachments = NULL,
-        .colorAttachmentCount = 1,
-        .pColorAttachments = &color_reference,
-        .pResolveAttachments = NULL,
-        .pDepthStencilAttachment = &depth_reference,
-        .preserveAttachmentCount = 0,
-        .pPreserveAttachments = NULL,
-    };
-    const VkRenderPassCreateInfo rp_info = {
-        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
-        .pNext = NULL,
-        .attachmentCount = 2,
-        .pAttachments = attachments,
-        .subpassCount = 1,
-        .pSubpasses = &subpass,
-        .dependencyCount = 0,
-        .pDependencies = NULL,
-    };
-    VkResult U_ASSERT_ONLY err;
-
-    err = vkCreateRenderPass(demo->device, &rp_info, NULL, &demo->render_pass);
-    assert(!err);
-}
-
-//TODO: Merge shader reading
-#ifndef __ANDROID__
-static VkShaderModule
-demo_prepare_shader_module(struct demo *demo, const void *code, size_t size) {
-    VkShaderModuleCreateInfo moduleCreateInfo;
-    VkShaderModule module;
-    VkResult U_ASSERT_ONLY err;
-
-    moduleCreateInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
-    moduleCreateInfo.pNext = NULL;
-
-    moduleCreateInfo.codeSize = size;
-    moduleCreateInfo.pCode = code;
-    moduleCreateInfo.flags = 0;
-    err = vkCreateShaderModule(demo->device, &moduleCreateInfo, NULL, &module);
-    assert(!err);
-
-    return module;
-}
-
-char *demo_read_spv(const char *filename, size_t *psize) {
-    long int size;
-    void *shader_code;
-    size_t retVal;
-
-    FILE *fp = fopen(filename, "rb");
-    if (!fp)
-        return NULL;
-
-    fseek(fp, 0L, SEEK_END);
-    size = ftell(fp);
-
-    fseek(fp, 0L, SEEK_SET);
-
-    shader_code = malloc(size);
-    retVal = fread(shader_code, size, 1, fp);
-    if (!retVal)
-        return NULL;
-
-    *psize = size;
-
-    fclose(fp);
-    return shader_code;
-}
-#endif
-
-static VkShaderModule demo_prepare_vs(struct demo *demo) {
-#ifdef __ANDROID__
-    VkShaderModuleCreateInfo sh_info = {};
-    sh_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
-
-#include "tri.vert.h"
-    sh_info.codeSize = sizeof(tri_vert);
-    sh_info.pCode = tri_vert;
-    VkResult U_ASSERT_ONLY err = vkCreateShaderModule(demo->device, &sh_info, NULL, &demo->vert_shader_module);
-    assert(!err);
-#else
-    void *vertShaderCode;
-    size_t size = 0;
-
-    vertShaderCode = demo_read_spv("tri-vert.spv", &size);
-
-    demo->vert_shader_module =
-        demo_prepare_shader_module(demo, vertShaderCode, size);
-
-    free(vertShaderCode);
-#endif
-
-    return demo->vert_shader_module;
-}
-
-static VkShaderModule demo_prepare_fs(struct demo *demo) {
-#ifdef __ANDROID__
-    VkShaderModuleCreateInfo sh_info = {};
-    sh_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
-
-#include "tri.frag.h"
-    sh_info.codeSize = sizeof(tri_frag);
-    sh_info.pCode = tri_frag;
-    VkResult U_ASSERT_ONLY err = vkCreateShaderModule(demo->device, &sh_info, NULL, &demo->frag_shader_module);
-    assert(!err);
-#else
-    void *fragShaderCode;
-    size_t size;
-
-    fragShaderCode = demo_read_spv("tri-frag.spv", &size);
-
-    demo->frag_shader_module =
-        demo_prepare_shader_module(demo, fragShaderCode, size);
-
-    free(fragShaderCode);
-#endif
-
-    return demo->frag_shader_module;
-}
-
-static void demo_prepare_pipeline(struct demo *demo) {
-    VkGraphicsPipelineCreateInfo pipeline;
-    VkPipelineCacheCreateInfo pipelineCache;
-
-    VkPipelineVertexInputStateCreateInfo vi;
-    VkPipelineInputAssemblyStateCreateInfo ia;
-    VkPipelineRasterizationStateCreateInfo rs;
-    VkPipelineColorBlendStateCreateInfo cb;
-    VkPipelineDepthStencilStateCreateInfo ds;
-    VkPipelineViewportStateCreateInfo vp;
-    VkPipelineMultisampleStateCreateInfo ms;
-    VkDynamicState dynamicStateEnables[VK_DYNAMIC_STATE_RANGE_SIZE];
-    VkPipelineDynamicStateCreateInfo dynamicState;
-
-    VkResult U_ASSERT_ONLY err;
-
-    memset(dynamicStateEnables, 0, sizeof dynamicStateEnables);
-    memset(&dynamicState, 0, sizeof dynamicState);
-    dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
-    dynamicState.pDynamicStates = dynamicStateEnables;
-
-    memset(&pipeline, 0, sizeof(pipeline));
-    pipeline.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
-    pipeline.layout = demo->pipeline_layout;
-
-    vi = demo->vertices.vi;
-
-    memset(&ia, 0, sizeof(ia));
-    ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
-    ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-
-    memset(&rs, 0, sizeof(rs));
-    rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
-    rs.polygonMode = VK_POLYGON_MODE_FILL;
-    rs.cullMode = VK_CULL_MODE_BACK_BIT;
-    rs.frontFace = VK_FRONT_FACE_CLOCKWISE;
-    rs.depthClampEnable = VK_FALSE;
-    rs.rasterizerDiscardEnable = VK_FALSE;
-    rs.depthBiasEnable = VK_FALSE;
-    rs.lineWidth = 1.0f;
-
-    memset(&cb, 0, sizeof(cb));
-    cb.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
-    VkPipelineColorBlendAttachmentState att_state[1];
-    memset(att_state, 0, sizeof(att_state));
-    att_state[0].colorWriteMask = 0xf;
-    att_state[0].blendEnable = VK_FALSE;
-    cb.attachmentCount = 1;
-    cb.pAttachments = att_state;
-
-    memset(&vp, 0, sizeof(vp));
-    vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
-    vp.viewportCount = 1;
-    dynamicStateEnables[dynamicState.dynamicStateCount++] =
-        VK_DYNAMIC_STATE_VIEWPORT;
-    vp.scissorCount = 1;
-    dynamicStateEnables[dynamicState.dynamicStateCount++] =
-        VK_DYNAMIC_STATE_SCISSOR;
-
-    memset(&ds, 0, sizeof(ds));
-    ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
-    ds.depthTestEnable = VK_TRUE;
-    ds.depthWriteEnable = VK_TRUE;
-    ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL;
-    ds.depthBoundsTestEnable = VK_FALSE;
-    ds.back.failOp = VK_STENCIL_OP_KEEP;
-    ds.back.passOp = VK_STENCIL_OP_KEEP;
-    ds.back.compareOp = VK_COMPARE_OP_ALWAYS;
-    ds.stencilTestEnable = VK_FALSE;
-    ds.front = ds.back;
-
-    memset(&ms, 0, sizeof(ms));
-    ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
-    ms.pSampleMask = NULL;
-    ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
-
-    // Two stages: vs and fs
-    pipeline.stageCount = 2;
-    VkPipelineShaderStageCreateInfo shaderStages[2];
-    memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
-
-    shaderStages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    shaderStages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
-    shaderStages[0].module = demo_prepare_vs(demo);
-    shaderStages[0].pName = "main";
-
-    shaderStages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
-    shaderStages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
-    shaderStages[1].module = demo_prepare_fs(demo);
-    shaderStages[1].pName = "main";
-
-    pipeline.pVertexInputState = &vi;
-    pipeline.pInputAssemblyState = &ia;
-    pipeline.pRasterizationState = &rs;
-    pipeline.pColorBlendState = &cb;
-    pipeline.pMultisampleState = &ms;
-    pipeline.pViewportState = &vp;
-    pipeline.pDepthStencilState = &ds;
-    pipeline.pStages = shaderStages;
-    pipeline.renderPass = demo->render_pass;
-    pipeline.pDynamicState = &dynamicState;
-
-    memset(&pipelineCache, 0, sizeof(pipelineCache));
-    pipelineCache.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
-
-    err = vkCreatePipelineCache(demo->device, &pipelineCache, NULL,
-                                &demo->pipelineCache);
-    assert(!err);
-    err = vkCreateGraphicsPipelines(demo->device, demo->pipelineCache, 1,
-                                    &pipeline, NULL, &demo->pipeline);
-    assert(!err);
-
-    vkDestroyPipelineCache(demo->device, demo->pipelineCache, NULL);
-
-    vkDestroyShaderModule(demo->device, demo->frag_shader_module, NULL);
-    vkDestroyShaderModule(demo->device, demo->vert_shader_module, NULL);
-}
-
-static void demo_prepare_descriptor_pool(struct demo *demo) {
-    const VkDescriptorPoolSize type_count = {
-        .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-        .descriptorCount = DEMO_TEXTURE_COUNT,
-    };
-    const VkDescriptorPoolCreateInfo descriptor_pool = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
-        .pNext = NULL,
-        .maxSets = 1,
-        .poolSizeCount = 1,
-        .pPoolSizes = &type_count,
-    };
-    VkResult U_ASSERT_ONLY err;
-
-    err = vkCreateDescriptorPool(demo->device, &descriptor_pool, NULL,
-                                 &demo->desc_pool);
-    assert(!err);
-}
-
-static void demo_prepare_descriptor_set(struct demo *demo) {
-    VkDescriptorImageInfo tex_descs[DEMO_TEXTURE_COUNT];
-    VkWriteDescriptorSet write;
-    VkResult U_ASSERT_ONLY err;
-    uint32_t i;
-
-    VkDescriptorSetAllocateInfo alloc_info = {
-        .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-        .pNext = NULL,
-        .descriptorPool = demo->desc_pool,
-        .descriptorSetCount = 1,
-        .pSetLayouts = &demo->desc_layout};
-    err = vkAllocateDescriptorSets(demo->device, &alloc_info, &demo->desc_set);
-    assert(!err);
-
-    memset(&tex_descs, 0, sizeof(tex_descs));
-    for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
-        tex_descs[i].sampler = demo->textures[i].sampler;
-        tex_descs[i].imageView = demo->textures[i].view;
-        tex_descs[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
-    }
-
-    memset(&write, 0, sizeof(write));
-    write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-    write.dstSet = demo->desc_set;
-    write.descriptorCount = DEMO_TEXTURE_COUNT;
-    write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
-    write.pImageInfo = tex_descs;
-
-    vkUpdateDescriptorSets(demo->device, 1, &write, 0, NULL);
-}
-
-static void demo_prepare_framebuffers(struct demo *demo) {
-    VkImageView attachments[2];
-    attachments[1] = demo->depth.view;
-
-    const VkFramebufferCreateInfo fb_info = {
-        .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-        .pNext = NULL,
-        .renderPass = demo->render_pass,
-        .attachmentCount = 2,
-        .pAttachments = attachments,
-        .width = demo->width,
-        .height = demo->height,
-        .layers = 1,
-    };
-    VkResult U_ASSERT_ONLY err;
-    uint32_t i;
-
-    demo->framebuffers = (VkFramebuffer *)malloc(demo->swapchainImageCount *
-                                                 sizeof(VkFramebuffer));
-    assert(demo->framebuffers);
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        attachments[0] = demo->buffers[i].view;
-        err = vkCreateFramebuffer(demo->device, &fb_info, NULL,
-                                  &demo->framebuffers[i]);
-        assert(!err);
-    }
-}
-
-static void demo_prepare(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-
-    const VkCommandPoolCreateInfo cmd_pool_info = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
-        .pNext = NULL,
-        .queueFamilyIndex = demo->graphics_queue_node_index,
-        .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
-    };
-    err = vkCreateCommandPool(demo->device, &cmd_pool_info, NULL,
-                              &demo->cmd_pool);
-    assert(!err);
-
-    const VkCommandBufferAllocateInfo cmd = {
-        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
-        .pNext = NULL,
-        .commandPool = demo->cmd_pool,
-        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
-        .commandBufferCount = 1,
-    };
-    err = vkAllocateCommandBuffers(demo->device, &cmd, &demo->draw_cmd);
-    assert(!err);
-
-    demo_prepare_buffers(demo);
-    demo_prepare_depth(demo);
-    demo_prepare_textures(demo);
-    demo_prepare_vertices(demo);
-    demo_prepare_descriptor_layout(demo);
-    demo_prepare_render_pass(demo);
-    demo_prepare_pipeline(demo);
-
-    demo_prepare_descriptor_pool(demo);
-    demo_prepare_descriptor_set(demo);
-
-    demo_prepare_framebuffers(demo);
-
-    demo->prepared = true;
-}
-
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-static void demo_run(struct demo *demo) {
-    if (!demo->prepared)
-        return;
-    demo_draw(demo);
-
-    if (demo->depthStencil > 0.99f)
-        demo->depthIncrement = -0.001f;
-    if (demo->depthStencil < 0.8f)
-        demo->depthIncrement = 0.001f;
-
-    demo->depthStencil += demo->depthIncrement;
-
-    demo->curFrame++;
-    if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount) {
-        PostQuitMessage(validation_error);
-    }
-}
-
-// On MS-Windows, make this a global, so it's available to WndProc()
-struct demo demo;
-
-// MS-Windows event handling function:
-LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-    char tmp_str[] = APP_LONG_NAME;
-
-    switch (uMsg) {
-    case WM_CREATE:
-        return 0;
-    case WM_CLOSE:
-        PostQuitMessage(validation_error);
-        return 0;
-    case WM_PAINT:
-        if (demo.prepared) {
-            demo_run(&demo);
-            break;
-        }
-    case WM_GETMINMAXINFO:     // set window's minimum size
-        ((MINMAXINFO*)lParam)->ptMinTrackSize = demo.minsize;
-        return 0;
-    case WM_SIZE:
-        // Resize the application to the new window size, except when
-        // it was minimized. Vulkan doesn't support images or swapchains
-        // with width=0 and height=0.
-        if (wParam != SIZE_MINIMIZED) {
-            demo.width = lParam & 0xffff;
-            demo.height = lParam & 0xffff0000 >> 16;
-            
-            if (demo.height < 64) demo.height = 64;
-
-            demo_resize(&demo);
-        }
-        break;
-    default:
-        break;
-    }
-    return (DefWindowProc(hWnd, uMsg, wParam, lParam));
-}
-
-static void demo_create_window(struct demo *demo) {
-    WNDCLASSEX win_class;
-
-    // Initialize the window class structure:
-    win_class.cbSize = sizeof(WNDCLASSEX);
-    win_class.style = CS_HREDRAW | CS_VREDRAW;
-    win_class.lpfnWndProc = WndProc;
-    win_class.cbClsExtra = 0;
-    win_class.cbWndExtra = 0;
-    win_class.hInstance = demo->connection; // hInstance
-    win_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-    win_class.hCursor = LoadCursor(NULL, IDC_ARROW);
-    win_class.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
-    win_class.lpszMenuName = NULL;
-    win_class.lpszClassName = demo->name;
-    win_class.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
-    // Register window class:
-    if (!RegisterClassEx(&win_class)) {
-        // It didn't work, so try to give a useful error:
-        printf("Unexpected error trying to start the application!\n");
-        fflush(stdout);
-        exit(1);
-    }
-    // Create window with the registered class:
-    RECT wr = {0, 0, demo->width, demo->height};
-    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
-    demo->window = CreateWindowEx(0,
-                                  demo->name,           // class name
-                                  demo->name,           // app name
-                                  WS_OVERLAPPEDWINDOW | // window style
-                                      WS_VISIBLE | WS_SYSMENU,
-                                  100, 100,           // x/y coords
-                                  wr.right - wr.left, // width
-                                  wr.bottom - wr.top, // height
-                                  NULL,               // handle to parent
-                                  NULL,               // handle to menu
-                                  demo->connection,   // hInstance
-                                  NULL);              // no extra parameters
-    if (!demo->window) {
-        // It didn't work, so try to give a useful error:
-        printf("Cannot create a window in which to draw!\n");
-        fflush(stdout);
-        exit(1);
-    }
-    // Window client area size must be at least 1 pixel high, to prevent crash.
-    demo->minsize.x = GetSystemMetrics(SM_CXMINTRACK);
-    demo->minsize.y = GetSystemMetrics(SM_CYMINTRACK) + 1;
-}
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
-static void demo_handle_event(struct demo *demo,
-                              const xcb_generic_event_t *event) {
-    switch (event->response_type & 0x7f) {
-    case XCB_EXPOSE:
-        demo_draw(demo);
-        break;
-    case XCB_CLIENT_MESSAGE:
-        if ((*(xcb_client_message_event_t *)event).data.data32[0] ==
-            (*demo->atom_wm_delete_window).atom) {
-            demo->quit = true;
-        }
-        break;
-    case XCB_KEY_RELEASE: {
-        const xcb_key_release_event_t *key =
-            (const xcb_key_release_event_t *)event;
-
-        if (key->detail == 0x9)
-            demo->quit = true;
-    } break;
-    case XCB_DESTROY_NOTIFY:
-        demo->quit = true;
-        break;
-    case XCB_CONFIGURE_NOTIFY: {
-        const xcb_configure_notify_event_t *cfg =
-            (const xcb_configure_notify_event_t *)event;
-        if ((demo->width != cfg->width) || (demo->height != cfg->height)) {
-            demo->width = cfg->width;
-            demo->height = cfg->height;
-            demo_resize(demo);
-        }
-    } break;
-    default:
-        break;
-    }
-}
-
-static void demo_run(struct demo *demo) {
-    xcb_flush(demo->connection);
-
-    while (!demo->quit) {
-        xcb_generic_event_t *event;
-
-        event = xcb_poll_for_event(demo->connection);
-        if (event) {
-            demo_handle_event(demo, event);
-            free(event);
-        }
-
-        demo_draw(demo);
-
-        if (demo->depthStencil > 0.99f)
-            demo->depthIncrement = -0.001f;
-        if (demo->depthStencil < 0.8f)
-            demo->depthIncrement = 0.001f;
-
-        demo->depthStencil += demo->depthIncrement;
-
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
-        demo->curFrame++;
-        if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
-            demo->quit = true;
-    }
-}
-
-static void demo_create_window(struct demo *demo) {
-    uint32_t value_mask, value_list[32];
-
-    demo->window = xcb_generate_id(demo->connection);
-
-    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
-    value_list[0] = demo->screen->black_pixel;
-    value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE |
-                    XCB_EVENT_MASK_STRUCTURE_NOTIFY;
-
-    xcb_create_window(demo->connection, XCB_COPY_FROM_PARENT, demo->window,
-                      demo->screen->root, 0, 0, demo->width, demo->height, 0,
-                      XCB_WINDOW_CLASS_INPUT_OUTPUT, demo->screen->root_visual,
-                      value_mask, value_list);
-
-    /* Magic code that will send notification when window is destroyed */
-    xcb_intern_atom_cookie_t cookie =
-        xcb_intern_atom(demo->connection, 1, 12, "WM_PROTOCOLS");
-    xcb_intern_atom_reply_t *reply =
-        xcb_intern_atom_reply(demo->connection, cookie, 0);
-
-    xcb_intern_atom_cookie_t cookie2 =
-        xcb_intern_atom(demo->connection, 0, 16, "WM_DELETE_WINDOW");
-    demo->atom_wm_delete_window =
-        xcb_intern_atom_reply(demo->connection, cookie2, 0);
-
-    xcb_change_property(demo->connection, XCB_PROP_MODE_REPLACE, demo->window,
-                        (*reply).atom, 4, 32, 1,
-                        &(*demo->atom_wm_delete_window).atom);
-    free(reply);
-
-    xcb_map_window(demo->connection, demo->window);
-}
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-static void demo_run(struct demo *demo) {
-
-    while (!demo->quit) {
-        demo_draw(demo);
-
-        if (demo->depthStencil > 0.99f)
-            demo->depthIncrement = -0.001f;
-        if (demo->depthStencil < 0.8f)
-            demo->depthIncrement = 0.001f;
-
-        demo->depthStencil += demo->depthIncrement;
-
-        // Wait for work to finish before updating MVP.
-        vkDeviceWaitIdle(demo->device);
-        demo->curFrame++;
-        if (demo->frameCount != INT32_MAX && demo->curFrame == demo->frameCount)
-            demo->quit = true;
-    }
-}
-
-static void handle_ping(void *data UNUSED,
-                        struct wl_shell_surface *shell_surface,
-                        uint32_t serial) {
-    wl_shell_surface_pong(shell_surface, serial);
-}
-
-static void handle_configure(void *data UNUSED,
-                             struct wl_shell_surface *shell_surface UNUSED,
-                             uint32_t edges UNUSED, int32_t width UNUSED,
-                             int32_t height UNUSED) {}
-
-static void handle_popup_done(void *data UNUSED,
-                              struct wl_shell_surface *shell_surface UNUSED) {}
-
-static const struct wl_shell_surface_listener shell_surface_listener = {
-    handle_ping, handle_configure, handle_popup_done};
-
-static void demo_create_window(struct demo *demo) {
-    demo->window = wl_compositor_create_surface(demo->compositor);
-    if (!demo->window) {
-        printf("Can not create wayland_surface from compositor!\n");
-        fflush(stdout);
-        exit(1);
-    }
-
-    demo->shell_surface = wl_shell_get_shell_surface(demo->shell, demo->window);
-    if (!demo->shell_surface) {
-        printf("Can not get shell_surface from wayland_surface!\n");
-        fflush(stdout);
-        exit(1);
-    }
-    wl_shell_surface_add_listener(demo->shell_surface, &shell_surface_listener,
-                                  demo);
-    wl_shell_surface_set_toplevel(demo->shell_surface);
-    wl_shell_surface_set_title(demo->shell_surface, APP_SHORT_NAME);
-}
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-static void demo_run(struct demo *demo) {
-    if (!demo->prepared)
-        return;
-    demo_draw(demo);
-
-    if (demo->depthStencil > 0.99f)
-        demo->depthIncrement = -0.001f;
-    if (demo->depthStencil < 0.8f)
-        demo->depthIncrement = 0.001f;
-
-    demo->depthStencil += demo->depthIncrement;
-
-    demo->curFrame++;
-}
-#endif
-
-/*
- * Return 1 (true) if all layer names specified in check_names
- * can be found in given layer properties.
- */
-static VkBool32 demo_check_layers(uint32_t check_count, char **check_names,
-                                  uint32_t layer_count,
-                                  VkLayerProperties *layers) {
-    for (uint32_t i = 0; i < check_count; i++) {
-        VkBool32 found = 0;
-        for (uint32_t j = 0; j < layer_count; j++) {
-            if (!strcmp(check_names[i], layers[j].layerName)) {
-                found = 1;
-                break;
-            }
-        }
-        if (!found) {
-            fprintf(stderr, "Cannot find layer: %s\n", check_names[i]);
-            return 0;
-        }
-    }
-    return 1;
-}
-
-static void demo_init_vk(struct demo *demo) {
-    VkResult err;
-    uint32_t instance_extension_count = 0;
-    uint32_t instance_layer_count = 0;
-    uint32_t validation_layer_count = 0;
-    char **instance_validation_layers = NULL;
-    demo->enabled_extension_count = 0;
-    demo->enabled_layer_count = 0;
-
-    char *instance_validation_layers_alt1[] = {
-        "VK_LAYER_LUNARG_standard_validation"
-    };
-
-    char *instance_validation_layers_alt2[] = {
-        "VK_LAYER_GOOGLE_threading",       "VK_LAYER_LUNARG_parameter_validation",
-        "VK_LAYER_LUNARG_object_tracker",  "VK_LAYER_LUNARG_image",
-        "VK_LAYER_LUNARG_core_validation", "VK_LAYER_LUNARG_swapchain",
-        "VK_LAYER_GOOGLE_unique_objects"
-    };
-
-    /* Look for validation layers */
-    VkBool32 validation_found = 0;
-    if (demo->validate) {
-
-        err = vkEnumerateInstanceLayerProperties(&instance_layer_count, NULL);
-        assert(!err);
-
-        instance_validation_layers = instance_validation_layers_alt1;
-        if (instance_layer_count > 0) {
-            VkLayerProperties *instance_layers =
-                    malloc(sizeof (VkLayerProperties) * instance_layer_count);
-            err = vkEnumerateInstanceLayerProperties(&instance_layer_count,
-                    instance_layers);
-            assert(!err);
-
-
-            validation_found = demo_check_layers(
-                    ARRAY_SIZE(instance_validation_layers_alt1),
-                    instance_validation_layers, instance_layer_count,
-                    instance_layers);
-            if (validation_found) {
-                demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
-                demo->enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
-                validation_layer_count = 1;
-            } else {
-                // use alternative set of validation layers
-                instance_validation_layers = instance_validation_layers_alt2;
-                demo->enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
-                validation_found = demo_check_layers(
-                    ARRAY_SIZE(instance_validation_layers_alt2),
-                    instance_validation_layers, instance_layer_count,
-                    instance_layers);
-                validation_layer_count =
-                    ARRAY_SIZE(instance_validation_layers_alt2);
-                for (uint32_t i = 0; i < validation_layer_count; i++) {
-                    demo->enabled_layers[i] = instance_validation_layers[i];
-                }
-            }
-            free(instance_layers);
-        }
-
-        if (!validation_found) {
-            ERR_EXIT("vkEnumerateInstanceLayerProperties failed to find "
-                    "required validation layer.\n\n"
-                    "Please look at the Getting Started guide for additional "
-                    "information.\n",
-                    "vkCreateInstance Failure");
-        }
-    }
-
-    /* Look for instance extensions */
-    VkBool32 surfaceExtFound = 0;
-    VkBool32 platformSurfaceExtFound = 0;
-    memset(demo->extension_names, 0, sizeof(demo->extension_names));
-
-    err = vkEnumerateInstanceExtensionProperties(
-        NULL, &instance_extension_count, NULL);
-    assert(!err);
-
-    if (instance_extension_count > 0) {
-        VkExtensionProperties *instance_extensions =
-            malloc(sizeof(VkExtensionProperties) * instance_extension_count);
-        err = vkEnumerateInstanceExtensionProperties(
-            NULL, &instance_extension_count, instance_extensions);
-        assert(!err);
-        for (uint32_t i = 0; i < instance_extension_count; i++) {
-            if (!strcmp(VK_KHR_SURFACE_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                surfaceExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_SURFACE_EXTENSION_NAME;
-            }
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-            if (!strcmp(VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                platformSurfaceExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
-            }
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
-            if (!strcmp(VK_KHR_XCB_SURFACE_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                platformSurfaceExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_XCB_SURFACE_EXTENSION_NAME;
-            }
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-            if (!strcmp(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                platformSurfaceExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
-            }
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-            if (!strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                platformSurfaceExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
-            }
-#endif
-            if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
-                        instance_extensions[i].extensionName)) {
-                if (demo->validate) {
-                    demo->extension_names[demo->enabled_extension_count++] =
-                        VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
-                }
-            }
-            assert(demo->enabled_extension_count < 64);
-        }
-
-        free(instance_extensions);
-    }
-
-    if (!surfaceExtFound) {
-        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
-                 "the " VK_KHR_SURFACE_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-    }
-    if (!platformSurfaceExtFound) {
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
-                 "the " VK_KHR_WIN32_SURFACE_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
-        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
-                 "the " VK_KHR_XCB_SURFACE_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
-                 "the " VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-        ERR_EXIT("vkEnumerateInstanceExtensionProperties failed to find "
-                 "the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-#endif
-    }
-    const VkApplicationInfo app = {
-        .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
-        .pNext = NULL,
-        .pApplicationName = APP_SHORT_NAME,
-        .applicationVersion = 0,
-        .pEngineName = APP_SHORT_NAME,
-        .engineVersion = 0,
-        .apiVersion = VK_API_VERSION_1_0,
-    };
-    VkInstanceCreateInfo inst_info = {
-        .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
-        .pNext = NULL,
-        .pApplicationInfo = &app,
-        .enabledLayerCount = demo->enabled_layer_count,
-        .ppEnabledLayerNames = (const char *const *)instance_validation_layers,
-        .enabledExtensionCount = demo->enabled_extension_count,
-        .ppEnabledExtensionNames = (const char *const *)demo->extension_names,
-    };
-
-    uint32_t gpu_count;
-
-    err = vkCreateInstance(&inst_info, NULL, &demo->inst);
-    if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
-        ERR_EXIT("Cannot find a compatible Vulkan installable client driver "
-                 "(ICD).\n\nPlease look at the Getting Started guide for "
-                 "additional information.\n",
-                 "vkCreateInstance Failure");
-    } else if (err == VK_ERROR_EXTENSION_NOT_PRESENT) {
-        ERR_EXIT("Cannot find a specified extension library"
-                 ".\nMake sure your layers path is set appropriately\n",
-                 "vkCreateInstance Failure");
-    } else if (err) {
-        ERR_EXIT("vkCreateInstance failed.\n\nDo you have a compatible Vulkan "
-                 "installable client driver (ICD) installed?\nPlease look at "
-                 "the Getting Started guide for additional information.\n",
-                 "vkCreateInstance Failure");
-    }
-
-    /* Make initial call to query gpu_count, then second call for gpu info*/
-    err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count, NULL);
-    assert(!err && gpu_count > 0);
-
-    if (gpu_count > 0) {
-        VkPhysicalDevice *physical_devices =
-            malloc(sizeof(VkPhysicalDevice) * gpu_count);
-        err = vkEnumeratePhysicalDevices(demo->inst, &gpu_count,
-                                         physical_devices);
-        assert(!err);
-        /* For tri demo we just grab the first physical device */
-        demo->gpu = physical_devices[0];
-        free(physical_devices);
-    } else {
-        ERR_EXIT("vkEnumeratePhysicalDevices reported zero accessible devices."
-                 "\n\nDo you have a compatible Vulkan installable client"
-                 " driver (ICD) installed?\nPlease look at the Getting Started"
-                 " guide for additional information.\n",
-                 "vkEnumeratePhysicalDevices Failure");
-    }
-
-    /* Look for device extensions */
-    uint32_t device_extension_count = 0;
-    VkBool32 swapchainExtFound = 0;
-    demo->enabled_extension_count = 0;
-    memset(demo->extension_names, 0, sizeof(demo->extension_names));
-
-    err = vkEnumerateDeviceExtensionProperties(demo->gpu, NULL,
-                                               &device_extension_count, NULL);
-    assert(!err);
-
-    if (device_extension_count > 0) {
-        VkExtensionProperties *device_extensions =
-                malloc(sizeof(VkExtensionProperties) * device_extension_count);
-        err = vkEnumerateDeviceExtensionProperties(
-            demo->gpu, NULL, &device_extension_count, device_extensions);
-        assert(!err);
-
-        for (uint32_t i = 0; i < device_extension_count; i++) {
-            if (!strcmp(VK_KHR_SWAPCHAIN_EXTENSION_NAME,
-                        device_extensions[i].extensionName)) {
-                swapchainExtFound = 1;
-                demo->extension_names[demo->enabled_extension_count++] =
-                    VK_KHR_SWAPCHAIN_EXTENSION_NAME;
-            }
-            assert(demo->enabled_extension_count < 64);
-        }
-
-        free(device_extensions);
-    }
-
-    if (!swapchainExtFound) {
-        ERR_EXIT("vkEnumerateDeviceExtensionProperties failed to find "
-                 "the " VK_KHR_SWAPCHAIN_EXTENSION_NAME
-                 " extension.\n\nDo you have a compatible "
-                 "Vulkan installable client driver (ICD) installed?\nPlease "
-                 "look at the Getting Started guide for additional "
-                 "information.\n",
-                 "vkCreateInstance Failure");
-    }
-
-    if (demo->validate) {
-        demo->CreateDebugReportCallback =
-            (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(
-                demo->inst, "vkCreateDebugReportCallbackEXT");
-        demo->DestroyDebugReportCallback =
-            (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(
-                demo->inst, "vkDestroyDebugReportCallbackEXT");
-        if (!demo->CreateDebugReportCallback) {
-            ERR_EXIT(
-                "GetProcAddr: Unable to find vkCreateDebugReportCallbackEXT\n",
-                "vkGetProcAddr Failure");
-        }
-        if (!demo->DestroyDebugReportCallback) {
-            ERR_EXIT(
-                "GetProcAddr: Unable to find vkDestroyDebugReportCallbackEXT\n",
-                "vkGetProcAddr Failure");
-        }
-        demo->DebugReportMessage =
-            (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(
-                demo->inst, "vkDebugReportMessageEXT");
-        if (!demo->DebugReportMessage) {
-            ERR_EXIT("GetProcAddr: Unable to find vkDebugReportMessageEXT\n",
-                     "vkGetProcAddr Failure");
-        }
-
-        VkDebugReportCallbackCreateInfoEXT dbgCreateInfo;
-        dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT;
-        dbgCreateInfo.flags =
-            VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
-        dbgCreateInfo.pfnCallback = demo->use_break ? BreakCallback : dbgFunc;
-        dbgCreateInfo.pUserData = demo;
-        dbgCreateInfo.pNext = NULL;
-        err = demo->CreateDebugReportCallback(demo->inst, &dbgCreateInfo, NULL,
-                                              &demo->msg_callback);
-        switch (err) {
-        case VK_SUCCESS:
-            break;
-        case VK_ERROR_OUT_OF_HOST_MEMORY:
-            ERR_EXIT("CreateDebugReportCallback: out of host memory\n",
-                     "CreateDebugReportCallback Failure");
-            break;
-        default:
-            ERR_EXIT("CreateDebugReportCallback: unknown failure\n",
-                     "CreateDebugReportCallback Failure");
-            break;
-        }
-    }
-
-    // Having these GIPA queries of device extension entry points both
-    // BEFORE and AFTER vkCreateDevice is a good test for the loader
-    GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceCapabilitiesKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceFormatsKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfacePresentModesKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, GetPhysicalDeviceSurfaceSupportKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, CreateSwapchainKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, DestroySwapchainKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, GetSwapchainImagesKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, AcquireNextImageKHR);
-    GET_INSTANCE_PROC_ADDR(demo->inst, QueuePresentKHR);
-
-    vkGetPhysicalDeviceProperties(demo->gpu, &demo->gpu_props);
-
-    // Query with NULL data to get count
-    vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count,
-                                             NULL);
-
-    demo->queue_props = (VkQueueFamilyProperties *)malloc(
-        demo->queue_count * sizeof(VkQueueFamilyProperties));
-    vkGetPhysicalDeviceQueueFamilyProperties(demo->gpu, &demo->queue_count,
-                                             demo->queue_props);
-    assert(demo->queue_count >= 1);
-
-    vkGetPhysicalDeviceFeatures(demo->gpu, &demo->gpu_features);
-
-    // Graphics queue and MemMgr queue can be separate.
-    // TODO: Add support for separate queues, including synchronization,
-    //       and appropriate tracking for QueueSubmit
-}
-
-static void demo_init_device(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-
-    float queue_priorities[1] = {0.0};
-    const VkDeviceQueueCreateInfo queue = {
-        .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
-        .pNext = NULL,
-        .queueFamilyIndex = demo->graphics_queue_node_index,
-        .queueCount = 1,
-        .pQueuePriorities = queue_priorities};
-
-
-    VkPhysicalDeviceFeatures features;
-    memset(&features, 0, sizeof(features));
-    if (demo->gpu_features.shaderClipDistance) {
-        features.shaderClipDistance = VK_TRUE;
-    }
-
-    VkDeviceCreateInfo device = {
-        .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
-        .pNext = NULL,
-        .queueCreateInfoCount = 1,
-        .pQueueCreateInfos = &queue,
-        .enabledLayerCount = 0,
-        .ppEnabledLayerNames = NULL,
-        .enabledExtensionCount = demo->enabled_extension_count,
-        .ppEnabledExtensionNames = (const char *const *)demo->extension_names,
-        .pEnabledFeatures = &features,
-    };
-
-    err = vkCreateDevice(demo->gpu, &device, NULL, &demo->device);
-    assert(!err);
-}
-
-static void demo_init_vk_swapchain(struct demo *demo) {
-    VkResult U_ASSERT_ONLY err;
-    uint32_t i;
-
-// Create a WSI surface for the window:
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-    VkWin32SurfaceCreateInfoKHR createInfo;
-    createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
-    createInfo.pNext = NULL;
-    createInfo.flags = 0;
-    createInfo.hinstance = demo->connection;
-    createInfo.hwnd = demo->window;
-
-    err =
-        vkCreateWin32SurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
-#elif defined(VK_USE_PLATFORM_XCB_KHR)
-    VkXcbSurfaceCreateInfoKHR createInfo;
-    createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
-    createInfo.pNext = NULL;
-    createInfo.flags = 0;
-    createInfo.connection = demo->connection;
-    createInfo.window = demo->window;
-
-    err = vkCreateXcbSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    VkWaylandSurfaceCreateInfoKHR createInfo;
-    createInfo.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR;
-    createInfo.pNext = NULL;
-    createInfo.flags = 0;
-    createInfo.display = demo->display;
-    createInfo.surface = demo->window;
-
-    err = vkCreateWaylandSurfaceKHR(demo->inst, &createInfo, NULL,
-                                    &demo->surface);
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-    VkAndroidSurfaceCreateInfoKHR createInfo;
-    createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
-    createInfo.pNext = NULL;
-    createInfo.flags = 0;
-    createInfo.window = (ANativeWindow*)(demo->window);
-
-    err = vkCreateAndroidSurfaceKHR(demo->inst, &createInfo, NULL, &demo->surface);
-#endif
-
-    // Iterate over each queue to learn whether it supports presenting:
-    VkBool32 *supportsPresent =
-        (VkBool32 *)malloc(demo->queue_count * sizeof(VkBool32));
-    for (i = 0; i < demo->queue_count; i++) {
-        demo->fpGetPhysicalDeviceSurfaceSupportKHR(demo->gpu, i, demo->surface,
-                                                   &supportsPresent[i]);
-    }
-
-    // Search for a graphics and a present queue in the array of queue
-    // families, try to find one that supports both
-    uint32_t graphicsQueueNodeIndex = UINT32_MAX;
-    uint32_t presentQueueNodeIndex = UINT32_MAX;
-    for (i = 0; i < demo->queue_count; i++) {
-        if ((demo->queue_props[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0) {
-            if (graphicsQueueNodeIndex == UINT32_MAX) {
-                graphicsQueueNodeIndex = i;
-            }
-
-            if (supportsPresent[i] == VK_TRUE) {
-                graphicsQueueNodeIndex = i;
-                presentQueueNodeIndex = i;
-                break;
-            }
-        }
-    }
-    if (presentQueueNodeIndex == UINT32_MAX) {
-        // If didn't find a queue that supports both graphics and present, then
-        // find a separate present queue.
-        for (uint32_t i = 0; i < demo->queue_count; ++i) {
-            if (supportsPresent[i] == VK_TRUE) {
-                presentQueueNodeIndex = i;
-                break;
-            }
-        }
-    }
-    free(supportsPresent);
-
-    // Generate error if could not find both a graphics and a present queue
-    if (graphicsQueueNodeIndex == UINT32_MAX ||
-        presentQueueNodeIndex == UINT32_MAX) {
-        ERR_EXIT("Could not find a graphics and a present queue\n",
-                 "Swapchain Initialization Failure");
-    }
-
-    // TODO: Add support for separate queues, including presentation,
-    //       synchronization, and appropriate tracking for QueueSubmit.
-    // NOTE: While it is possible for an application to use a separate graphics
-    //       and a present queues, this demo program assumes it is only using
-    //       one:
-    if (graphicsQueueNodeIndex != presentQueueNodeIndex) {
-        ERR_EXIT("Could not find a common graphics and a present queue\n",
-                 "Swapchain Initialization Failure");
-    }
-
-    demo->graphics_queue_node_index = graphicsQueueNodeIndex;
-
-    demo_init_device(demo);
-
-    vkGetDeviceQueue(demo->device, demo->graphics_queue_node_index, 0,
-                     &demo->queue);
-
-    // Get the list of VkFormat's that are supported:
-    uint32_t formatCount;
-    err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface,
-                                                     &formatCount, NULL);
-    assert(!err);
-    VkSurfaceFormatKHR *surfFormats =
-        (VkSurfaceFormatKHR *)malloc(formatCount * sizeof(VkSurfaceFormatKHR));
-    err = demo->fpGetPhysicalDeviceSurfaceFormatsKHR(demo->gpu, demo->surface,
-                                                     &formatCount, surfFormats);
-    assert(!err);
-    // If the format list includes just one entry of VK_FORMAT_UNDEFINED,
-    // the surface has no preferred format.  Otherwise, at least one
-    // supported format will be returned.
-    if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
-        demo->format = VK_FORMAT_B8G8R8A8_UNORM;
-    } else {
-        assert(formatCount >= 1);
-        demo->format = surfFormats[0].format;
-    }
-    demo->color_space = surfFormats[0].colorSpace;
-
-    demo->quit = false;
-    demo->curFrame = 0;
-
-    // Get Memory information and properties
-    vkGetPhysicalDeviceMemoryProperties(demo->gpu, &demo->memory_properties);
-}
-
-#if defined(VK_USE_PLATFORM_WAYLAND_KHR) && !defined(VK_USE_PLATFORM_XCB_KHR)
-static void registry_handle_global(void *data, struct wl_registry *registry,
-                                   uint32_t name, const char *interface,
-                                   uint32_t version UNUSED) {
-    struct demo *demo = data;
-    if (strcmp(interface, "wl_compositor") == 0) {
-        demo->compositor =
-            wl_registry_bind(registry, name, &wl_compositor_interface, 3);
-        /* Todo: When xdg_shell protocol has stablized, we should move wl_shell
-         * tp xdg_shell */
-    } else if (strcmp(interface, "wl_shell") == 0) {
-        demo->shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
-    }
-}
-
-static void registry_handle_global_remove(void *data UNUSED,
-                                          struct wl_registry *registry UNUSED,
-                                          uint32_t name UNUSED) {}
-
-static const struct wl_registry_listener registry_listener = {
-    registry_handle_global, registry_handle_global_remove};
-#endif
-
-static void demo_init_connection(struct demo *demo) {
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    const xcb_setup_t *setup;
-    xcb_screen_iterator_t iter;
-    int scr;
-
-    demo->connection = xcb_connect(NULL, &scr);
-    if (xcb_connection_has_error(demo->connection) > 0) {
-        printf("Cannot find a compatible Vulkan installable client driver "
-               "(ICD).\nExiting ...\n");
-        fflush(stdout);
-        exit(1);
-    }
-
-    setup = xcb_get_setup(demo->connection);
-    iter = xcb_setup_roots_iterator(setup);
-    while (scr-- > 0)
-        xcb_screen_next(&iter);
-
-    demo->screen = iter.data;
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    demo->display = wl_display_connect(NULL);
-
-    if (demo->display == NULL) {
-        printf("Cannot find a compatible Vulkan installable client driver "
-               "(ICD).\nExiting ...\n");
-        fflush(stdout);
-        exit(1);
-    }
-
-    demo->registry = wl_display_get_registry(demo->display);
-    wl_registry_add_listener(demo->registry, &registry_listener, demo);
-    wl_display_dispatch(demo->display);
-#endif // _WIN32
-}
-
-static void demo_init(struct demo *demo, const int argc, const char *argv[])
-{
-    memset(demo, 0, sizeof(*demo));
-    demo->frameCount = INT32_MAX;
-
-    for (int i = 1; i < argc; i++) {
-        if (strcmp(argv[i], "--use_staging") == 0) {
-            demo->use_staging_buffer = true;
-            continue;
-        }
-        if (strcmp(argv[i], "--break") == 0) {
-            demo->use_break = true;
-            continue;
-        }
-        if (strcmp(argv[i], "--validate") == 0) {
-            demo->validate = true;
-            continue;
-        }
-        if (strcmp(argv[i], "--c") == 0 && demo->frameCount == INT32_MAX &&
-            i < argc - 1 && sscanf(argv[i + 1], "%d", &demo->frameCount) == 1 &&
-            demo->frameCount >= 0) {
-            i++;
-            continue;
-        }
-        if (strcmp(argv[i], "--suppress_popups") == 0) {
-            demo->suppress_popups = true;
-            continue;
-        }
-
-        fprintf(stderr, "Usage:\n  %s [--use_staging] [--validate] [--break] "
-                        "[--c <framecount>] [--suppress_popups]\n",
-                APP_SHORT_NAME);
-        fflush(stderr);
-        exit(1);
-    }
-
-    demo_init_connection(demo);
-    demo_init_vk(demo);
-
-    demo->width = 300;
-    demo->height = 300;
-    demo->depthStencil = 1.0;
-    demo->depthIncrement = -0.01f;
-}
-
-static void demo_cleanup(struct demo *demo) {
-    uint32_t i;
-
-    demo->prepared = false;
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL);
-    }
-    free(demo->framebuffers);
-    vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL);
-
-    if (demo->setup_cmd) {
-        vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd);
-    }
-    vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd);
-    vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
-
-    vkDestroyPipeline(demo->device, demo->pipeline, NULL);
-    vkDestroyRenderPass(demo->device, demo->render_pass, NULL);
-    vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL);
-    vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL);
-
-    vkDestroyBuffer(demo->device, demo->vertices.buf, NULL);
-    vkFreeMemory(demo->device, demo->vertices.mem, NULL);
-
-    for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
-        vkDestroyImageView(demo->device, demo->textures[i].view, NULL);
-        vkDestroyImage(demo->device, demo->textures[i].image, NULL);
-        vkFreeMemory(demo->device, demo->textures[i].mem, NULL);
-        vkDestroySampler(demo->device, demo->textures[i].sampler, NULL);
-    }
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        vkDestroyImageView(demo->device, demo->buffers[i].view, NULL);
-    }
-
-    vkDestroyImageView(demo->device, demo->depth.view, NULL);
-    vkDestroyImage(demo->device, demo->depth.image, NULL);
-    vkFreeMemory(demo->device, demo->depth.mem, NULL);
-
-    demo->fpDestroySwapchainKHR(demo->device, demo->swapchain, NULL);
-    free(demo->buffers);
-
-    vkDestroyDevice(demo->device, NULL);
-    if (demo->validate) {
-        demo->DestroyDebugReportCallback(demo->inst, demo->msg_callback, NULL);
-    }
-    vkDestroySurfaceKHR(demo->inst, demo->surface, NULL);
-    vkDestroyInstance(demo->inst, NULL);
-
-    free(demo->queue_props);
-
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    xcb_destroy_window(demo->connection, demo->window);
-    xcb_disconnect(demo->connection);
-    free(demo->atom_wm_delete_window);
-#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
-    wl_shell_surface_destroy(demo->shell_surface);
-    wl_surface_destroy(demo->window);
-    wl_shell_destroy(demo->shell);
-    wl_compositor_destroy(demo->compositor);
-    wl_registry_destroy(demo->registry);
-    wl_display_disconnect(demo->display);
-#endif
-}
-
-static void demo_resize(struct demo *demo) {
-    uint32_t i;
-
-    // Don't react to resize until after first initialization.
-    if (!demo->prepared) {
-        return;
-    }
-    // In order to properly resize the window, we must re-create the swapchain
-    // AND redo the command buffers, etc.
-    //
-    // First, perform part of the demo_cleanup() function:
-    demo->prepared = false;
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        vkDestroyFramebuffer(demo->device, demo->framebuffers[i], NULL);
-    }
-    free(demo->framebuffers);
-    vkDestroyDescriptorPool(demo->device, demo->desc_pool, NULL);
-
-    if (demo->setup_cmd) {
-        vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->setup_cmd);
-    }
-    vkFreeCommandBuffers(demo->device, demo->cmd_pool, 1, &demo->draw_cmd);
-    vkDestroyCommandPool(demo->device, demo->cmd_pool, NULL);
-
-    vkDestroyPipeline(demo->device, demo->pipeline, NULL);
-    vkDestroyRenderPass(demo->device, demo->render_pass, NULL);
-    vkDestroyPipelineLayout(demo->device, demo->pipeline_layout, NULL);
-    vkDestroyDescriptorSetLayout(demo->device, demo->desc_layout, NULL);
-
-    vkDestroyBuffer(demo->device, demo->vertices.buf, NULL);
-    vkFreeMemory(demo->device, demo->vertices.mem, NULL);
-
-    for (i = 0; i < DEMO_TEXTURE_COUNT; i++) {
-        vkDestroyImageView(demo->device, demo->textures[i].view, NULL);
-        vkDestroyImage(demo->device, demo->textures[i].image, NULL);
-        vkFreeMemory(demo->device, demo->textures[i].mem, NULL);
-        vkDestroySampler(demo->device, demo->textures[i].sampler, NULL);
-    }
-
-    for (i = 0; i < demo->swapchainImageCount; i++) {
-        vkDestroyImageView(demo->device, demo->buffers[i].view, NULL);
-    }
-
-    vkDestroyImageView(demo->device, demo->depth.view, NULL);
-    vkDestroyImage(demo->device, demo->depth.image, NULL);
-    vkFreeMemory(demo->device, demo->depth.mem, NULL);
-
-    free(demo->buffers);
-
-    // Second, re-perform the demo_prepare() function, which will re-create the
-    // swapchain:
-    demo_prepare(demo);
-}
-
-#if defined(VK_USE_PLATFORM_WIN32_KHR)
-// Include header required for parsing the command line options.
-#include <shellapi.h>
-
-int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
-                     LPSTR pCmdLine, int nCmdShow) {
-    MSG msg;   // message
-    bool done; // flag saying when app is complete
-    int argc;
-    char **argv;
-
-    // Use the CommandLine functions to get the command line arguments.
-    // Unfortunately, Microsoft outputs
-    // this information as wide characters for Unicode, and we simply want the
-    // Ascii version to be compatible
-    // with the non-Windows side.  So, we have to convert the information to
-    // Ascii character strings.
-    LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc);
-    if (NULL == commandLineArgs) {
-        argc = 0;
-    }
-
-    if (argc > 0) {
-        argv = (char **)malloc(sizeof(char *) * argc);
-        if (argv == NULL) {
-            argc = 0;
-        } else {
-            for (int iii = 0; iii < argc; iii++) {
-                size_t wideCharLen = wcslen(commandLineArgs[iii]);
-                size_t numConverted = 0;
-
-                argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1));
-                if (argv[iii] != NULL) {
-                    wcstombs_s(&numConverted, argv[iii], wideCharLen + 1,
-                               commandLineArgs[iii], wideCharLen + 1);
-                }
-            }
-        }
-    } else {
-        argv = NULL;
-    }
-
-    demo_init(&demo, argc, argv);
-
-    // Free up the items we had to allocate for the command line arguments.
-    if (argc > 0 && argv != NULL) {
-        for (int iii = 0; iii < argc; iii++) {
-            if (argv[iii] != NULL) {
-                free(argv[iii]);
-            }
-        }
-        free(argv);
-    }
-
-    demo.connection = hInstance;
-    strncpy(demo.name, "tri", APP_NAME_STR_LEN);
-    demo_create_window(&demo);
-    demo_init_vk_swapchain(&demo);
-
-    demo_prepare(&demo);
-
-    done = false; // initialize loop condition variable
-    /* main message loop*/
-    while (!done) {
-        PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
-        if (msg.message == WM_QUIT) // check for a quit message
-        {
-            done = true; // if found, quit app
-        } else {
-            /* Translate and dispatch to event queue*/
-            TranslateMessage(&msg);
-            DispatchMessage(&msg);
-        }
-        RedrawWindow(demo.window, NULL, NULL, RDW_INTERNALPAINT);
-    }
-
-    demo_cleanup(&demo);
-
-    return (int)msg.wParam;
-}
-
-#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
-
-#include <android/log.h>
-#include <android_native_app_glue.h>
-static bool initialized = false;
-static bool active = false;
-struct demo demo;
-
-static int32_t processInput(struct android_app* app, AInputEvent* event) {
-    return 0;
-}
-
-static void processCommand(struct android_app* app, int32_t cmd) {
-    switch(cmd) {
-        case APP_CMD_INIT_WINDOW: {
-            if (app->window) {
-                demo_init(&demo, 0, NULL);
-                demo.window = (void*)app->window;
-                demo_init_vk_swapchain(&demo);
-                demo_prepare(&demo);
-                initialized = true;
-            }
-            break;
-        }
-        case APP_CMD_GAINED_FOCUS: {
-            active = true;
-            break;
-        }
-        case APP_CMD_LOST_FOCUS: {
-            active = false;
-            break;
-        }
-    }
-}
-
-
-
-void android_main(struct android_app *app)
-{
-    app_dummy();
-
-#ifdef ANDROID
-    int vulkanSupport = InitVulkan();
-    if (vulkanSupport == 0)
-        return;
-#endif
-
-    app->onAppCmd = processCommand;
-    app->onInputEvent = processInput;
-
-    while(1) {
-        int events;
-        struct android_poll_source* source;
-        while (ALooper_pollAll(active ? 0 : -1, NULL, &events, (void**)&source) >= 0) {
-            if (source) {
-                source->process(app, source);
-            }
-
-            if (app->destroyRequested != 0) {
-                demo_cleanup(&demo);
-                return;
-            }
-        }
-        if (initialized && active) {
-            demo_run(&demo);
-        }
-    }
-
-}
-
-#elif defined(VK_USE_PLATFORM_XCB_KHR) | defined(VK_USE_PLATFORM_WAYLAND_KHR)
-
-int main(const int argc, const char *argv[]) {
-    struct demo demo;
-
-    demo_init(&demo, argc, argv);
-    demo_create_window(&demo);
-    demo_init_vk_swapchain(&demo);
-
-    demo_prepare(&demo);
-    demo_run(&demo);
-
-    demo_cleanup(&demo);
-
-    return validation_error;
-}
-
-#endif
diff --git a/demos/tri.frag b/demos/tri.frag
deleted file mode 100644
index 3606f2e..0000000
--- a/demos/tri.frag
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 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.
- */
-/*
- * Fragment shader for tri demo
- */
-#version 400
-#extension GL_ARB_separate_shader_objects : enable
-#extension GL_ARB_shading_language_420pack : enable
-layout (binding = 0) uniform sampler2D tex;
-layout (location = 0) in vec2 texcoord;
-layout (location = 0) out vec4 uFragColor;
-void main() {
-   uFragColor = texture(tex, texcoord);
-}
diff --git a/demos/tri.vcxproj.user b/demos/tri.vcxproj.user
deleted file mode 100755
index fc118aa..0000000
--- a/demos/tri.vcxproj.user
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>

-<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

-    <LocalDebuggerEnvironment>VK_LAYER_PATH=..\layers\Debug</LocalDebuggerEnvironment>

-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>

-  </PropertyGroup>

-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

-    <LocalDebuggerEnvironment>VK_LAYER_PATH=..\layers\Release</LocalDebuggerEnvironment>

-    <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>

-  </PropertyGroup>

-</Project>

diff --git a/demos/tri.vert b/demos/tri.vert
deleted file mode 100644
index d4788d8..0000000
--- a/demos/tri.vert
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 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.
- */
-/*
- * Vertex shader used by tri demo.
- */
-#version 400
-#extension GL_ARB_separate_shader_objects : enable
-#extension GL_ARB_shading_language_420pack : enable
-layout (location = 0) in vec4 pos;
-layout (location = 1) in vec2 attr;
-layout (location = 0) out vec2 texcoord;
-out gl_PerVertex {
-        vec4 gl_Position;
-};
-void main() {
-   texcoord = attr;
-   gl_Position = pos;
-}
diff --git a/demos/vulkaninfo.c b/demos/vulkaninfo.c
index e6467fc..419469a 100644
--- a/demos/vulkaninfo.c
+++ b/demos/vulkaninfo.c
@@ -1083,7 +1083,7 @@
     printf("\tsparseResidency16Samples                = %u\n", features->sparseResidency16Samples               );
     printf("\tsparseResidencyAliased                  = %u\n", features->sparseResidencyAliased                 );
     printf("\tvariableMultisampleRate                 = %u\n", features->variableMultisampleRate                );
-    printf("\tiheritedQueries                         = %u\n", features->inheritedQueries                       );
+    printf("\tinheritedQueries                        = %u\n", features->inheritedQueries                       );
 }
 
 static void app_dump_sparse_props(const VkPhysicalDeviceSparseProperties *sparseProps)
diff --git a/generator.py b/generator.py
index 2868496..043121c 100755
--- a/generator.py
+++ b/generator.py
@@ -15,8 +15,6 @@
 # limitations under the License.
 
 import os,re,sys
-from collections import namedtuple
-import xml.etree.ElementTree as etree
 
 def write( *args, **kwargs ):
     file = kwargs.pop('file',sys.stdout)
@@ -41,6 +39,11 @@
     else:
         return None
 
+# apiName - returns True if name is a Vulkan name (vk/Vk/VK prefix, or a
+# function pointer type), False otherwise.
+def apiName(str):
+    return str[0:2].lower() == 'vk' or str[0:3] == 'PFN'
+
 # Primary sort key for regSortFeatures.
 # Sorts by category of the feature name string:
 #   Core API features (those defined with a <feature> tag)
@@ -86,7 +89,8 @@
 # Registry.apiGen() and by base OutputGenerator objects.
 #
 # Members
-#   filename - name of file to generate, or None to write to stdout.
+#   filename - basename of file to generate, or None to write to stdout.
+#   directory - directory in which to generate filename
 #   apiname - string matching <api> 'apiname' attribute, e.g. 'gl'.
 #   profile - string specifying API profile , e.g. 'core', or None.
 #   versions - regex matching API versions to process interfaces for.
@@ -113,6 +117,7 @@
     """Represents options during header production from an API registry"""
     def __init__(self,
                  filename = None,
+                 directory = '.',
                  apiname = None,
                  profile = None,
                  versions = '.*',
@@ -122,6 +127,7 @@
                  removeExtensions = None,
                  sortProcedure = regSortFeatures):
         self.filename          = filename
+        self.directory         = directory
         self.apiname           = apiname
         self.profile           = profile
         self.versions          = self.emptyRegex(versions)
@@ -139,285 +145,6 @@
         else:
             return pat
 
-# CGeneratorOptions - subclass of GeneratorOptions.
-#
-# Adds options used by COutputGenerator objects during C language header
-# generation.
-#
-# Additional members
-#   prefixText - list of strings to prefix generated header with
-#     (usually a copyright statement + calling convention macros).
-#   protectFile - True if multiple inclusion protection should be
-#     generated (based on the filename) around the entire header.
-#   protectFeature - True if #ifndef..#endif protection should be
-#     generated around a feature interface in the header file.
-#   genFuncPointers - True if function pointer typedefs should be
-#     generated
-#   protectProto - If conditional protection should be generated
-#     around prototype declarations, set to either '#ifdef'
-#     to require opt-in (#ifdef protectProtoStr) or '#ifndef'
-#     to require opt-out (#ifndef protectProtoStr). Otherwise
-#     set to None.
-#   protectProtoStr - #ifdef/#ifndef symbol to use around prototype
-#     declarations, if protectProto is set
-#   apicall - string to use for the function declaration prefix,
-#     such as APICALL on Windows.
-#   apientry - string to use for the calling convention macro,
-#     in typedefs, such as APIENTRY.
-#   apientryp - string to use for the calling convention macro
-#     in function pointer typedefs, such as APIENTRYP.
-#   indentFuncProto - True if prototype declarations should put each
-#     parameter on a separate line
-#   indentFuncPointer - True if typedefed function pointers should put each
-#     parameter on a separate line
-#   alignFuncParam - if nonzero and parameters are being put on a
-#     separate line, align parameter names at the specified column
-class CGeneratorOptions(GeneratorOptions):
-    """Represents options during C interface generation for headers"""
-    def __init__(self,
-                 filename = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 protectFile = True,
-                 protectFeature = True,
-                 protectProto = None,
-                 protectProtoStr = None,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 indentFuncProto = True,
-                 indentFuncPointer = False,
-                 alignFuncParam = 0):
-        GeneratorOptions.__init__(self, filename, apiname, profile,
-                                  versions, emitversions, defaultExtensions,
-                                  addExtensions, removeExtensions, sortProcedure)
-        self.prefixText      = prefixText
-        self.genFuncPointers = genFuncPointers
-        self.protectFile     = protectFile
-        self.protectFeature  = protectFeature
-        self.protectProto    = protectProto
-        self.protectProtoStr = protectProtoStr
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.indentFuncProto = indentFuncProto
-        self.indentFuncPointer = indentFuncPointer
-        self.alignFuncParam  = alignFuncParam
-
-# DocGeneratorOptions - subclass of GeneratorOptions.
-#
-# Shares many members with CGeneratorOptions, since
-# both are writing C-style declarations:
-#
-#   prefixText - list of strings to prefix generated header with
-#     (usually a copyright statement + calling convention macros).
-#   apicall - string to use for the function declaration prefix,
-#     such as APICALL on Windows.
-#   apientry - string to use for the calling convention macro,
-#     in typedefs, such as APIENTRY.
-#   apientryp - string to use for the calling convention macro
-#     in function pointer typedefs, such as APIENTRYP.
-#   genDirectory - directory into which to generate include files
-#   indentFuncProto - True if prototype declarations should put each
-#     parameter on a separate line
-#   indentFuncPointer - True if typedefed function pointers should put each
-#     parameter on a separate line
-#   alignFuncParam - if nonzero and parameters are being put on a
-#     separate line, align parameter names at the specified column
-#
-# Additional members:
-#
-class DocGeneratorOptions(GeneratorOptions):
-    """Represents options during C interface generation for Asciidoc"""
-    def __init__(self,
-                 filename = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 genDirectory = 'gen',
-                 indentFuncProto = True,
-                 indentFuncPointer = False,
-                 alignFuncParam = 0,
-                 expandEnumerants = True):
-        GeneratorOptions.__init__(self, filename, apiname, profile,
-                                  versions, emitversions, defaultExtensions,
-                                  addExtensions, removeExtensions, sortProcedure)
-        self.prefixText      = prefixText
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.genDirectory    = genDirectory
-        self.indentFuncProto = indentFuncProto
-        self.indentFuncPointer = indentFuncPointer
-        self.alignFuncParam  = alignFuncParam
-        self.expandEnumerants = expandEnumerants
-
-# ThreadGeneratorOptions - subclass of GeneratorOptions.
-#
-# Adds options used by COutputGenerator objects during C language header
-# generation.
-#
-# Additional members
-#   prefixText - list of strings to prefix generated header with
-#     (usually a copyright statement + calling convention macros).
-#   protectFile - True if multiple inclusion protection should be
-#     generated (based on the filename) around the entire header.
-#   protectFeature - True if #ifndef..#endif protection should be
-#     generated around a feature interface in the header file.
-#   genFuncPointers - True if function pointer typedefs should be
-#     generated
-#   protectProto - True if #ifdef..#endif protection should be
-#     generated around prototype declarations
-#   protectProtoStr - #ifdef symbol to use around prototype
-#     declarations, if protected
-#   apicall - string to use for the function declaration prefix,
-#     such as APICALL on Windows.
-#   apientry - string to use for the calling convention macro,
-#     in typedefs, such as APIENTRY.
-#   apientryp - string to use for the calling convention macro
-#     in function pointer typedefs, such as APIENTRYP.
-#   indentFuncProto - True if prototype declarations should put each
-#     parameter on a separate line
-#   indentFuncPointer - True if typedefed function pointers should put each
-#     parameter on a separate line
-#   alignFuncParam - if nonzero and parameters are being put on a
-#     separate line, align parameter names at the specified column
-class ThreadGeneratorOptions(GeneratorOptions):
-    """Represents options during C interface generation for headers"""
-    def __init__(self,
-                 filename = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 protectFile = True,
-                 protectFeature = True,
-                 protectProto = True,
-                 protectProtoStr = True,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 indentFuncProto = True,
-                 indentFuncPointer = False,
-                 alignFuncParam = 0,
-                 genDirectory = None):
-        GeneratorOptions.__init__(self, filename, apiname, profile,
-                                  versions, emitversions, defaultExtensions,
-                                  addExtensions, removeExtensions, sortProcedure)
-        self.prefixText      = prefixText
-        self.genFuncPointers = genFuncPointers
-        self.protectFile     = protectFile
-        self.protectFeature  = protectFeature
-        self.protectProto    = protectProto
-        self.protectProtoStr = protectProtoStr
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.indentFuncProto = indentFuncProto
-        self.indentFuncPointer = indentFuncPointer
-        self.alignFuncParam  = alignFuncParam
-        self.genDirectory    = genDirectory
-
-
-# ParamCheckerGeneratorOptions - subclass of GeneratorOptions.
-#
-# Adds options used by ParamCheckerOutputGenerator objects during parameter validation
-# generation.
-#
-# Additional members
-#   prefixText - list of strings to prefix generated header with
-#     (usually a copyright statement + calling convention macros).
-#   protectFile - True if multiple inclusion protection should be
-#     generated (based on the filename) around the entire header.
-#   protectFeature - True if #ifndef..#endif protection should be
-#     generated around a feature interface in the header file.
-#   genFuncPointers - True if function pointer typedefs should be
-#     generated
-#   protectProto - If conditional protection should be generated
-#     around prototype declarations, set to either '#ifdef'
-#     to require opt-in (#ifdef protectProtoStr) or '#ifndef'
-#     to require opt-out (#ifndef protectProtoStr). Otherwise
-#     set to None.
-#   protectProtoStr - #ifdef/#ifndef symbol to use around prototype
-#     declarations, if protectProto is set
-#   apicall - string to use for the function declaration prefix,
-#     such as APICALL on Windows.
-#   apientry - string to use for the calling convention macro,
-#     in typedefs, such as APIENTRY.
-#   apientryp - string to use for the calling convention macro
-#     in function pointer typedefs, such as APIENTRYP.
-#   indentFuncProto - True if prototype declarations should put each
-#     parameter on a separate line
-#   indentFuncPointer - True if typedefed function pointers should put each
-#     parameter on a separate line
-#   alignFuncParam - if nonzero and parameters are being put on a
-#     separate line, align parameter names at the specified column
-class ParamCheckerGeneratorOptions(GeneratorOptions):
-    """Represents options during C interface generation for headers"""
-    def __init__(self,
-                 filename = None,
-                 apiname = None,
-                 profile = None,
-                 versions = '.*',
-                 emitversions = '.*',
-                 defaultExtensions = None,
-                 addExtensions = None,
-                 removeExtensions = None,
-                 sortProcedure = regSortFeatures,
-                 prefixText = "",
-                 genFuncPointers = True,
-                 protectFile = True,
-                 protectFeature = True,
-                 protectProto = None,
-                 protectProtoStr = None,
-                 apicall = '',
-                 apientry = '',
-                 apientryp = '',
-                 indentFuncProto = True,
-                 indentFuncPointer = False,
-                 alignFuncParam = 0,
-                 genDirectory = None):
-        GeneratorOptions.__init__(self, filename, apiname, profile,
-                                  versions, emitversions, defaultExtensions,
-                                  addExtensions, removeExtensions, sortProcedure)
-        self.prefixText      = prefixText
-        self.genFuncPointers = genFuncPointers
-        self.protectFile     = protectFile
-        self.protectFeature  = protectFeature
-        self.protectProto    = protectProto
-        self.protectProtoStr = protectProtoStr
-        self.apicall         = apicall
-        self.apientry        = apientry
-        self.apientryp       = apientryp
-        self.indentFuncProto = indentFuncProto
-        self.indentFuncPointer = indentFuncPointer
-        self.alignFuncParam  = alignFuncParam
-        self.genDirectory    = genDirectory
-
-
 # OutputGenerator - base class for generating API interfaces.
 # Manages basic logic, logging, and output file control
 # Derived classes actually generate formatted output.
@@ -432,6 +159,8 @@
 #   *args - print()-style arguments
 # setExtMap(map) - specify a dictionary map from extension names to
 #   numbers, used in creating values for extension enumerants.
+# makeDir(directory) - create a directory, if not already done.
+#   Generally called from derived generators creating hierarchies.
 # beginFile(genOpts) - start a new interface file
 #   genOpts - GeneratorOptions controlling what's generated and how
 # endFile() - finish an interface file, closing it when done
@@ -451,6 +180,8 @@
 #   name - enum name
 # genCmd(cmdinfo) - generate interface for a command
 #   cmdinfo - CmdInfo for a command
+# isEnumRequired(enumElem) - return True if this <enum> element is required
+#   elem - <enum> element to test
 # makeCDecls(cmd) - return C prototype and function pointer typedef for a
 #     <command> Element, as a list of two strings
 #   cmd - Element for the <command>
@@ -458,6 +189,18 @@
 #
 class OutputGenerator:
     """Generate specified API interfaces in a specific style, such as a C header"""
+    #
+    # categoryToPath - map XML 'category' to include file directory name
+    categoryToPath = {
+        'bitmask'      : 'flags',
+        'enum'         : 'enums',
+        'funcpointer'  : 'funcpointers',
+        'handle'       : 'handles',
+        'define'       : 'defines',
+        'basetype'     : 'basetypes',
+    }
+    #
+    # Constructor
     def __init__(self,
                  errFile = sys.stderr,
                  warnFile = sys.stderr,
@@ -473,6 +216,7 @@
         # Used for extension enum value generation
         self.extBase      = 1000000000
         self.extBlockSize = 1000
+        self.madeDirs = {}
     #
     # logMsg - write a message of different categories to different
     #   destinations.
@@ -559,16 +303,22 @@
             return [numVal, value]
         return [None, None]
     #
+    def makeDir(self, path):
+        self.logMsg('diag', 'OutputGenerator::makeDir(' + path + ')')
+        if not (path in self.madeDirs.keys()):
+            # This can get race conditions with multiple writers, see
+            # https://stackoverflow.com/questions/273192/
+            if not os.path.exists(path):
+                os.makedirs(path)
+            self.madeDirs[path] = None
+    #
     def beginFile(self, genOpts):
         self.genOpts = genOpts
         #
         # Open specified output file. Not done in constructor since a
         # Generator can be used without writing to a file.
         if (self.genOpts.filename != None):
-            if (self.genOpts.genDirectory != None):
-                self.outFile = open(os.path.join(self.genOpts.genDirectory, self.genOpts.filename), 'w')
-            else:
-                self.outFile = open(self.genOpts.filename, 'w')
+            self.outFile = open(self.genOpts.directory + '/' + self.genOpts.filename, 'w')
         else:
             self.outFile = sys.stdout
     def endFile(self):
@@ -641,7 +391,10 @@
                 # Align at specified column, if possible
                 paramdecl = paramdecl.rstrip()
                 oldLen = len(paramdecl)
-                paramdecl = paramdecl.ljust(aligncol)
+                # This works around a problem where very long type names -
+                # longer than the alignment column - would run into the tail
+                # text.
+                paramdecl = paramdecl.ljust(aligncol-1) + ' '
                 newLen = len(paramdecl)
                 self.logMsg('diag', 'Adjust length of parameter decl from', oldLen, 'to', newLen, ':', paramdecl)
             paramdecl += text + tail
@@ -663,6 +416,14 @@
             paramdecl += text + tail
         return newLen
     #
+    # isEnumRequired(elem) - return True if this <enum> element is
+    # required, False otherwise
+    # elem - <enum> element to test
+    def isEnumRequired(self, elem):
+        return (elem.get('extname') is None or
+                re.match(self.genOpts.addExtensions, elem.get('extname')) is not None or
+                self.genOpts.defaultExtensions == elem.get('supported'))
+    #
     # makeCDecls - return C prototype and function pointer typedef for a
     #   command, as a two-element list of strings.
     # cmd - Element containing a <command> tag
@@ -735,2986 +496,3 @@
     def setRegistry(self, registry):
         self.registry = registry
         #
-
-# COutputGenerator - subclass of OutputGenerator.
-# Generates C-language API interfaces.
-#
-# ---- methods ----
-# COutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# beginFeature(interface, emit)
-# endFeature()
-# genType(typeinfo,name)
-# genStruct(typeinfo,name)
-# genGroup(groupinfo,name)
-# genEnum(enuminfo, name)
-# genCmd(cmdinfo)
-class COutputGenerator(OutputGenerator):
-    """Generate specified API interfaces in a specific style, such as a C header"""
-    # This is an ordered list of sections in the header file.
-    TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
-                     'group', 'bitmask', 'funcpointer', 'struct']
-    ALL_SECTIONS = TYPE_SECTIONS + ['commandPointer', 'command']
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-        # Internal state - accumulators for different inner block text
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-    #
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        # C-specific
-        #
-        # Multiple inclusion protection & C++ wrappers.
-        if (genOpts.protectFile and self.genOpts.filename):
-            headerSym = re.sub('\.h', '_h_',
-                               os.path.basename(self.genOpts.filename)).upper()
-            write('#ifndef', headerSym, file=self.outFile)
-            write('#define', headerSym, '1', file=self.outFile)
-            self.newline()
-        write('#ifdef __cplusplus', file=self.outFile)
-        write('extern "C" {', file=self.outFile)
-        write('#endif', file=self.outFile)
-        self.newline()
-        #
-        # User-supplied prefix text, if any (list of strings)
-        if (genOpts.prefixText):
-            for s in genOpts.prefixText:
-                write(s, file=self.outFile)
-        #
-        # Some boilerplate describing what was generated - this
-        # will probably be removed later since the extensions
-        # pattern may be very long.
-        # write('/* Generated C header for:', file=self.outFile)
-        # write(' * API:', genOpts.apiname, file=self.outFile)
-        # if (genOpts.profile):
-        #     write(' * Profile:', genOpts.profile, file=self.outFile)
-        # write(' * Versions considered:', genOpts.versions, file=self.outFile)
-        # write(' * Versions emitted:', genOpts.emitversions, file=self.outFile)
-        # write(' * Default extensions included:', genOpts.defaultExtensions, file=self.outFile)
-        # write(' * Additional extensions included:', genOpts.addExtensions, file=self.outFile)
-        # write(' * Extensions removed:', genOpts.removeExtensions, file=self.outFile)
-        # write(' */', file=self.outFile)
-    def endFile(self):
-        # C-specific
-        # Finish C++ wrapper and multiple inclusion protection
-        self.newline()
-        write('#ifdef __cplusplus', file=self.outFile)
-        write('}', file=self.outFile)
-        write('#endif', file=self.outFile)
-        if (self.genOpts.protectFile and self.genOpts.filename):
-            self.newline()
-            write('#endif', file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-        # C-specific
-        # Accumulate includes, defines, types, enums, function pointer typedefs,
-        # end function prototypes separately for this feature. They're only
-        # printed in endFeature().
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-    def endFeature(self):
-        # C-specific
-        # Actually write the interface to the output file.
-        if (self.emit):
-            self.newline()
-            if (self.genOpts.protectFeature):
-                write('#ifndef', self.featureName, file=self.outFile)
-            # If type declarations are needed by other features based on
-            # this one, it may be necessary to suppress the ExtraProtect,
-            # or move it below the 'for section...' loop.
-            if (self.featureExtraProtect != None):
-                write('#ifdef', self.featureExtraProtect, file=self.outFile)
-            write('#define', self.featureName, '1', file=self.outFile)
-            for section in self.TYPE_SECTIONS:
-                contents = self.sections[section]
-                if contents:
-                    write('\n'.join(contents), file=self.outFile)
-                    self.newline()
-            if (self.genOpts.genFuncPointers and self.sections['commandPointer']):
-                write('\n'.join(self.sections['commandPointer']), file=self.outFile)
-                self.newline()
-            if (self.sections['command']):
-                if (self.genOpts.protectProto):
-                    write(self.genOpts.protectProto,
-                          self.genOpts.protectProtoStr, file=self.outFile)
-                write('\n'.join(self.sections['command']), end='', file=self.outFile)
-                if (self.genOpts.protectProto):
-                    write('#endif', file=self.outFile)
-                else:
-                    self.newline()
-            if (self.featureExtraProtect != None):
-                write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
-            if (self.genOpts.protectFeature):
-                write('#endif /*', self.featureName, '*/', file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-    #
-    # Append a definition to the specified section
-    def appendSection(self, section, text):
-        # self.sections[section].append('SECTION: ' + section + '\n')
-        self.sections[section].append(text)
-    #
-    # Type generation
-    def genType(self, typeinfo, name):
-        OutputGenerator.genType(self, typeinfo, name)
-        typeElem = typeinfo.elem
-        # If the type is a struct type, traverse the imbedded <member> tags
-        # generating a structure. Otherwise, emit the tag text.
-        category = typeElem.get('category')
-        if (category == 'struct' or category == 'union'):
-            self.genStruct(typeinfo, name)
-        else:
-            # Replace <apientry /> tags with an APIENTRY-style string
-            # (from self.genOpts). Copy other text through unchanged.
-            # If the resulting text is an empty string, don't emit it.
-            s = noneStr(typeElem.text)
-            for elem in typeElem:
-                if (elem.tag == 'apientry'):
-                    s += self.genOpts.apientry + noneStr(elem.tail)
-                else:
-                    s += noneStr(elem.text) + noneStr(elem.tail)
-            if s:
-                # Add extra newline after multi-line entries.
-                if '\n' in s:
-                    s += '\n'
-                self.appendSection(category, s)
-    #
-    # Struct (e.g. C "struct" type) generation.
-    # This is a special case of the <type> tag where the contents are
-    # interpreted as a set of <member> tags instead of freeform C
-    # C type declarations. The <member> tags are just like <param>
-    # tags - they are a declaration of a struct or union member.
-    # Only simple member declarations are supported (no nested
-    # structs etc.)
-    def genStruct(self, typeinfo, typeName):
-        OutputGenerator.genStruct(self, typeinfo, typeName)
-        body = 'typedef ' + typeinfo.elem.get('category') + ' ' + typeName + ' {\n'
-        # paramdecl = self.makeCParamDecl(typeinfo.elem, self.genOpts.alignFuncParam)
-        targetLen = 0;
-        for member in typeinfo.elem.findall('.//member'):
-            targetLen = max(targetLen, self.getCParamTypeLength(member))
-        for member in typeinfo.elem.findall('.//member'):
-            body += self.makeCParamDecl(member, targetLen + 4)
-            body += ';\n'
-        body += '} ' + typeName + ';\n'
-        self.appendSection('struct', body)
-    #
-    # Group (e.g. C "enum" type) generation.
-    # These are concatenated together with other types.
-    def genGroup(self, groupinfo, groupName):
-        OutputGenerator.genGroup(self, groupinfo, groupName)
-        groupElem = groupinfo.elem
-
-        expandName = re.sub(r'([0-9a-z_])([A-Z0-9][^A-Z0-9]?)',r'\1_\2',groupName).upper()
-
-        expandPrefix = expandName
-        expandSuffix = ''
-        expandSuffixMatch = re.search(r'[A-Z][A-Z]+$',groupName)
-        if expandSuffixMatch:
-            expandSuffix = '_' + expandSuffixMatch.group()
-            # Strip off the suffix from the prefix
-            expandPrefix = expandName.rsplit(expandSuffix, 1)[0]
-
-        # Prefix
-        body = "\ntypedef enum " + groupName + " {\n"
-
-        isEnum = ('FLAG_BITS' not in expandPrefix)
-
-        # Loop over the nested 'enum' tags. Keep track of the minimum and
-        # maximum numeric values, if they can be determined; but only for
-        # core API enumerants, not extension enumerants. This is inferred
-        # by looking for 'extends' attributes.
-        minName = None
-        for elem in groupElem.findall('enum'):
-            # Convert the value to an integer and use that to track min/max.
-            # Values of form -(number) are accepted but nothing more complex.
-            # Should catch exceptions here for more complex constructs. Not yet.
-            (numVal,strVal) = self.enumToValue(elem, True)
-            name = elem.get('name')
-
-            # Extension enumerants are only included if they are requested
-            # in addExtensions or match defaultExtensions.
-            if (elem.get('extname') is None or
-              re.match(self.genOpts.addExtensions,elem.get('extname')) is not None or
-              self.genOpts.defaultExtensions == elem.get('supported')):
-                body += "    " + name + " = " + strVal + ",\n"
-
-            if (isEnum  and elem.get('extends') is None):
-                if (minName == None):
-                    minName = maxName = name
-                    minValue = maxValue = numVal
-                elif (numVal < minValue):
-                    minName = name
-                    minValue = numVal
-                elif (numVal > maxValue):
-                    maxName = name
-                    maxValue = numVal
-        # Generate min/max value tokens and a range-padding enum. Need some
-        # additional padding to generate correct names...
-        if isEnum:
-            body += "    " + expandPrefix + "_BEGIN_RANGE" + expandSuffix + " = " + minName + ",\n"
-            body += "    " + expandPrefix + "_END_RANGE" + expandSuffix + " = " + maxName + ",\n"
-            body += "    " + expandPrefix + "_RANGE_SIZE" + expandSuffix + " = (" + maxName + " - " + minName + " + 1),\n"
-
-        body += "    " + expandPrefix + "_MAX_ENUM" + expandSuffix + " = 0x7FFFFFFF\n"
-
-        # Postfix
-        body += "} " + groupName + ";"
-        if groupElem.get('type') == 'bitmask':
-            section = 'bitmask'
-        else:
-            section = 'group'
-        self.appendSection(section, body)
-    # Enumerant generation
-    # <enum> tags may specify their values in several ways, but are usually
-    # just integers.
-    def genEnum(self, enuminfo, name):
-        OutputGenerator.genEnum(self, enuminfo, name)
-        (numVal,strVal) = self.enumToValue(enuminfo.elem, False)
-        body = '#define ' + name.ljust(33) + ' ' + strVal
-        self.appendSection('enum', body)
-    #
-    # Command generation
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        #
-        decls = self.makeCDecls(cmdinfo.elem)
-        self.appendSection('command', decls[0] + '\n')
-        if (self.genOpts.genFuncPointers):
-            self.appendSection('commandPointer', decls[1])
-
-# DocOutputGenerator - subclass of OutputGenerator.
-# Generates AsciiDoc includes with C-language API interfaces, for reference
-# pages and the Vulkan specification. Similar to COutputGenerator, but
-# each interface is written into a different file as determined by the
-# options, only actual C types are emitted, and none of the boilerplate
-# preprocessor code is emitted.
-#
-# ---- methods ----
-# DocOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# beginFeature(interface, emit)
-# endFeature()
-# genType(typeinfo,name)
-# genStruct(typeinfo,name)
-# genGroup(groupinfo,name)
-# genEnum(enuminfo, name)
-# genCmd(cmdinfo)
-class DocOutputGenerator(OutputGenerator):
-    """Generate specified API interfaces in a specific style, such as a C header"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-    #
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-    def endFile(self):
-        OutputGenerator.endFile(self)
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-    def endFeature(self):
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-    #
-    # Generate an include file
-    #
-    # directory - subdirectory to put file in
-    # basename - base name of the file
-    # contents - contents of the file (Asciidoc boilerplate aside)
-    def writeInclude(self, directory, basename, contents):
-        # Create file
-        filename = self.genOpts.genDirectory + '/' + directory + '/' + basename + '.txt'
-        self.logMsg('diag', '# Generating include file:', filename)
-        fp = open(filename, 'w')
-        # Asciidoc anchor
-        write('// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry', file=fp)
-        write('ifndef::doctype-manpage[]', file=fp)
-        write('[[{0},{0}]]'.format(basename), file=fp)
-        write('["source","{basebackend@docbook:c++:cpp}",title=""]', file=fp)
-        write('endif::doctype-manpage[]', file=fp)
-        write('ifdef::doctype-manpage[]', file=fp)
-        write('["source","{basebackend@docbook:c++:cpp}"]', file=fp)
-        write('endif::doctype-manpage[]', file=fp)
-        write('------------------------------------------------------------------------------', file=fp)
-        write(contents, file=fp)
-        write('------------------------------------------------------------------------------', file=fp)
-        fp.close()
-    #
-    # Type generation
-    def genType(self, typeinfo, name):
-        OutputGenerator.genType(self, typeinfo, name)
-        typeElem = typeinfo.elem
-        # If the type is a struct type, traverse the imbedded <member> tags
-        # generating a structure. Otherwise, emit the tag text.
-        category = typeElem.get('category')
-        if (category == 'struct' or category == 'union'):
-            self.genStruct(typeinfo, name)
-        else:
-            # Replace <apientry /> tags with an APIENTRY-style string
-            # (from self.genOpts). Copy other text through unchanged.
-            # If the resulting text is an empty string, don't emit it.
-            s = noneStr(typeElem.text)
-            for elem in typeElem:
-                if (elem.tag == 'apientry'):
-                    s += self.genOpts.apientry + noneStr(elem.tail)
-                else:
-                    s += noneStr(elem.text) + noneStr(elem.tail)
-            if (len(s) > 0):
-                if (category == 'bitmask'):
-                    self.writeInclude('flags', name, s + '\n')
-                elif (category == 'enum'):
-                    self.writeInclude('enums', name, s + '\n')
-                elif (category == 'funcpointer'):
-                    self.writeInclude('funcpointers', name, s+ '\n')
-                else:
-                    self.logMsg('diag', '# NOT writing include file for type:',
-                        name, 'category: ', category)
-            else:
-                self.logMsg('diag', '# NOT writing empty include file for type', name)
-    #
-    # Struct (e.g. C "struct" type) generation.
-    # This is a special case of the <type> tag where the contents are
-    # interpreted as a set of <member> tags instead of freeform C
-    # C type declarations. The <member> tags are just like <param>
-    # tags - they are a declaration of a struct or union member.
-    # Only simple member declarations are supported (no nested
-    # structs etc.)
-    def genStruct(self, typeinfo, typeName):
-        OutputGenerator.genStruct(self, typeinfo, typeName)
-        s = 'typedef ' + typeinfo.elem.get('category') + ' ' + typeName + ' {\n'
-        # paramdecl = self.makeCParamDecl(typeinfo.elem, self.genOpts.alignFuncParam)
-        targetLen = 0;
-        for member in typeinfo.elem.findall('.//member'):
-            targetLen = max(targetLen, self.getCParamTypeLength(member))
-        for member in typeinfo.elem.findall('.//member'):
-            s += self.makeCParamDecl(member, targetLen + 4)
-            s += ';\n'
-        s += '} ' + typeName + ';'
-        self.writeInclude('structs', typeName, s)
-    #
-    # Group (e.g. C "enum" type) generation.
-    # These are concatenated together with other types.
-    def genGroup(self, groupinfo, groupName):
-        OutputGenerator.genGroup(self, groupinfo, groupName)
-        groupElem = groupinfo.elem
-
-        # See if we need min/max/num/padding at end
-        expand = self.genOpts.expandEnumerants
-
-        if expand:
-            expandName = re.sub(r'([0-9a-z_])([A-Z0-9][^A-Z0-9]?)',r'\1_\2',groupName).upper()
-            isEnum = ('FLAG_BITS' not in expandName)
-
-            expandPrefix = expandName
-            expandSuffix = ''
-
-            # Look for a suffix
-            expandSuffixMatch = re.search(r'[A-Z][A-Z]+$',groupName)
-            if expandSuffixMatch:
-                expandSuffix = '_' + expandSuffixMatch.group()
-                # Strip off the suffix from the prefix
-                expandPrefix = expandName.rsplit(expandSuffix, 1)[0]
-
-        # Prefix
-        s = "typedef enum " + groupName + " {\n"
-
-        # Loop over the nested 'enum' tags. Keep track of the minimum and
-        # maximum numeric values, if they can be determined.
-        minName = None
-        for elem in groupElem.findall('enum'):
-            # Convert the value to an integer and use that to track min/max.
-            # Values of form -(number) are accepted but nothing more complex.
-            # Should catch exceptions here for more complex constructs. Not yet.
-            (numVal,strVal) = self.enumToValue(elem, True)
-            name = elem.get('name')
-
-            # Extension enumerants are only included if they are requested
-            # in addExtensions or match defaultExtensions.
-            if (elem.get('extname') is None or
-              re.match(self.genOpts.addExtensions,elem.get('extname')) is not None or
-              self.genOpts.defaultExtensions == elem.get('supported')):
-                s += "    " + name + " = " + strVal + ",\n"
-
-            if (expand and isEnum and elem.get('extends') is None):
-                if (minName == None):
-                    minName = maxName = name
-                    minValue = maxValue = numVal
-                elif (numVal < minValue):
-                    minName = name
-                    minValue = numVal
-                elif (numVal > maxValue):
-                    maxName = name
-                    maxValue = numVal
-        # Generate min/max value tokens and a range-padding enum. Need some
-        # additional padding to generate correct names...
-        if (expand):
-            s += "\n"
-            if isEnum:
-                s += "    " + expandPrefix + "_BEGIN_RANGE" + expandSuffix + " = " + minName + ",\n"
-                s += "    " + expandPrefix + "_END_RANGE" + expandSuffix + " = " + maxName + ",\n"
-                s += "    " + expandPrefix + "_RANGE_SIZE" + expandSuffix + " = (" + maxName + " - " + minName + " + 1),\n"
-
-            s += "    " + expandPrefix + "_MAX_ENUM" + expandSuffix + " = 0x7FFFFFFF\n"
-        # Postfix
-        s += "} " + groupName + ";"
-        self.writeInclude('enums', groupName, s)
-    # Enumerant generation
-    # <enum> tags may specify their values in several ways, but are usually
-    # just integers.
-    def genEnum(self, enuminfo, name):
-        OutputGenerator.genEnum(self, enuminfo, name)
-        (numVal,strVal) = self.enumToValue(enuminfo.elem, False)
-        s = '#define ' + name.ljust(33) + ' ' + strVal
-        self.logMsg('diag', '# NOT writing compile-time constant', name)
-        # self.writeInclude('consts', name, s)
-    #
-    # Command generation
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        #
-        decls = self.makeCDecls(cmdinfo.elem)
-        self.writeInclude('protos', name, decls[0])
-
-# PyOutputGenerator - subclass of OutputGenerator.
-# Generates Python data structures describing API names.
-# Similar to DocOutputGenerator, but writes a single
-# file.
-#
-# ---- methods ----
-# PyOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# genType(typeinfo,name)
-# genStruct(typeinfo,name)
-# genGroup(groupinfo,name)
-# genEnum(enuminfo, name)
-# genCmd(cmdinfo)
-class PyOutputGenerator(OutputGenerator):
-    """Generate specified API interfaces in a specific style, such as a C header"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-    #
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        for dict in [ 'flags', 'enums', 'structs', 'consts', 'enums',
-          'consts', 'protos', 'funcpointers' ]:
-            write(dict, '= {}', file=self.outFile)
-    def endFile(self):
-        OutputGenerator.endFile(self)
-    #
-    # Add a name from the interface
-    #
-    # dict - type of name (see beginFile above)
-    # name - name to add
-    # value - A serializable Python value for the name
-    def addName(self, dict, name, value=None):
-        write(dict + "['" + name + "'] = ", value, file=self.outFile)
-    #
-    # Type generation
-    # For 'struct' or 'union' types, defer to genStruct() to
-    #   add to the dictionary.
-    # For 'bitmask' types, add the type name to the 'flags' dictionary,
-    #   with the value being the corresponding 'enums' name defining
-    #   the acceptable flag bits.
-    # For 'enum' types, add the type name to the 'enums' dictionary,
-    #   with the value being '@STOPHERE@' (because this case seems
-    #   never to happen).
-    # For 'funcpointer' types, add the type name to the 'funcpointers'
-    #   dictionary.
-    # For 'handle' and 'define' types, add the handle or #define name
-    #   to the 'struct' dictionary, because that's how the spec sources
-    #   tag these types even though they aren't structs.
-    def genType(self, typeinfo, name):
-        OutputGenerator.genType(self, typeinfo, name)
-        typeElem = typeinfo.elem
-        # If the type is a struct type, traverse the imbedded <member> tags
-        # generating a structure. Otherwise, emit the tag text.
-        category = typeElem.get('category')
-        if (category == 'struct' or category == 'union'):
-            self.genStruct(typeinfo, name)
-        else:
-            # Extract the type name
-            # (from self.genOpts). Copy other text through unchanged.
-            # If the resulting text is an empty string, don't emit it.
-            count = len(noneStr(typeElem.text))
-            for elem in typeElem:
-                count += len(noneStr(elem.text)) + len(noneStr(elem.tail))
-            if (count > 0):
-                if (category == 'bitmask'):
-                    requiredEnum = typeElem.get('requires')
-                    self.addName('flags', name, enquote(requiredEnum))
-                elif (category == 'enum'):
-                    # This case never seems to come up!
-                    # @enums   C 'enum' name           Dictionary of enumerant names
-                    self.addName('enums', name, enquote('@STOPHERE@'))
-                elif (category == 'funcpointer'):
-                    self.addName('funcpointers', name, None)
-                elif (category == 'handle' or category == 'define'):
-                    self.addName('structs', name, None)
-                else:
-                    write('# Unprocessed type:', name, 'category:', category, file=self.outFile)
-            else:
-                write('# Unprocessed type:', name, file=self.outFile)
-    #
-    # Struct (e.g. C "struct" type) generation.
-    #
-    # Add the struct name to the 'structs' dictionary, with the
-    # value being an ordered list of the struct member names.
-    def genStruct(self, typeinfo, typeName):
-        OutputGenerator.genStruct(self, typeinfo, typeName)
-
-        members = [member.text for member in typeinfo.elem.findall('.//member/name')]
-        self.addName('structs', typeName, members)
-    #
-    # Group (e.g. C "enum" type) generation.
-    # These are concatenated together with other types.
-    #
-    # Add the enum type name to the 'enums' dictionary, with
-    #   the value being an ordered list of the enumerant names.
-    # Add each enumerant name to the 'consts' dictionary, with
-    #   the value being the enum type the enumerant is part of.
-    def genGroup(self, groupinfo, groupName):
-        OutputGenerator.genGroup(self, groupinfo, groupName)
-        groupElem = groupinfo.elem
-
-        # @enums   C 'enum' name           Dictionary of enumerant names
-        # @consts  C enumerant/const name  Name of corresponding 'enums' key
-
-        # Loop over the nested 'enum' tags. Keep track of the minimum and
-        # maximum numeric values, if they can be determined.
-        enumerants = [elem.get('name') for elem in groupElem.findall('enum')]
-        for name in enumerants:
-            self.addName('consts', name, enquote(groupName))
-        self.addName('enums', groupName, enumerants)
-    # Enumerant generation (compile-time constants)
-    #
-    # Add the constant name to the 'consts' dictionary, with the
-    #   value being None to indicate that the constant isn't
-    #   an enumeration value.
-    def genEnum(self, enuminfo, name):
-        OutputGenerator.genEnum(self, enuminfo, name)
-
-        # @consts  C enumerant/const name  Name of corresponding 'enums' key
-
-        self.addName('consts', name, None)
-    #
-    # Command generation
-    #
-    # Add the command name to the 'protos' dictionary, with the
-    #   value being an ordered list of the parameter names.
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-
-        params = [param.text for param in cmdinfo.elem.findall('param/name')]
-        self.addName('protos', name, params)
-
-# ValidityOutputGenerator - subclass of OutputGenerator.
-# Generates AsciiDoc includes of valid usage information, for reference
-# pages and the Vulkan specification. Similar to DocOutputGenerator.
-#
-# ---- methods ----
-# ValidityOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# beginFeature(interface, emit)
-# endFeature()
-# genCmd(cmdinfo)
-class ValidityOutputGenerator(OutputGenerator):
-    """Generate specified API interfaces in a specific style, such as a C header"""
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-    def endFile(self):
-        OutputGenerator.endFile(self)
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-    def endFeature(self):
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-
-    def makeParameterName(self, name):
-        return 'pname:' + name
-
-    def makeStructName(self, name):
-        return 'sname:' + name
-
-    def makeBaseTypeName(self, name):
-        return 'basetype:' + name
-
-    def makeEnumerationName(self, name):
-        return 'elink:' + name
-
-    def makeEnumerantName(self, name):
-        return 'ename:' + name
-
-    def makeFLink(self, name):
-        return 'flink:' + name
-
-    #
-    # Generate an include file
-    #
-    # directory - subdirectory to put file in
-    # basename - base name of the file
-    # contents - contents of the file (Asciidoc boilerplate aside)
-    def writeInclude(self, directory, basename, validity, threadsafety, commandpropertiesentry, successcodes, errorcodes):
-        # Create file
-        filename = self.genOpts.genDirectory + '/' + directory + '/' + basename + '.txt'
-        self.logMsg('diag', '# Generating include file:', filename)
-        fp = open(filename, 'w')
-        # Asciidoc anchor
-        write('// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry', file=fp)
-
-        # Valid Usage
-        if validity is not None:
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('.Valid Usage', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('ifdef::doctype-manpage[]', file=fp)
-            write('Valid Usage', file=fp)
-            write('-----------', file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write(validity, file=fp, end='')
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('', file=fp)
-
-        # Host Synchronization
-        if threadsafety is not None:
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('.Host Synchronization', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('ifdef::doctype-manpage[]', file=fp)
-            write('Host Synchronization', file=fp)
-            write('--------------------', file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write(threadsafety, file=fp, end='')
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('', file=fp)
-
-        # Command Properties - contained within a block, to avoid table numbering
-        if commandpropertiesentry is not None:
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('.Command Properties', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('ifdef::doctype-manpage[]', file=fp)
-            write('Command Properties', file=fp)
-            write('------------------', file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('[options="header", width="100%"]', file=fp)
-            write('|=====================', file=fp)
-            write('|Command Buffer Levels|Render Pass Scope|Supported Queue Types', file=fp)
-            write(commandpropertiesentry, file=fp)
-            write('|=====================', file=fp)
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('', file=fp)
-
-        # Success Codes - contained within a block, to avoid table numbering
-        if successcodes is not None or errorcodes is not None:
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('.Return Codes', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('ifdef::doctype-manpage[]', file=fp)
-            write('Return Codes', file=fp)
-            write('------------', file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            if successcodes is not None:
-                write('ifndef::doctype-manpage[]', file=fp)
-                write('<<fundamentals-successcodes,Success>>::', file=fp)
-                write('endif::doctype-manpage[]', file=fp)
-                write('ifdef::doctype-manpage[]', file=fp)
-                write('On success, this command returns::', file=fp)
-                write('endif::doctype-manpage[]', file=fp)
-                write(successcodes, file=fp)
-            if errorcodes is not None:
-                write('ifndef::doctype-manpage[]', file=fp)
-                write('<<fundamentals-errorcodes,Failure>>::', file=fp)
-                write('endif::doctype-manpage[]', file=fp)
-                write('ifdef::doctype-manpage[]', file=fp)
-                write('On failure, this command returns::', file=fp)
-                write('endif::doctype-manpage[]', file=fp)
-                write(errorcodes, file=fp)
-            write('ifndef::doctype-manpage[]', file=fp)
-            write('*' * 80, file=fp)
-            write('endif::doctype-manpage[]', file=fp)
-            write('', file=fp)
-
-        fp.close()
-
-    #
-    # Check if the parameter passed in is a pointer
-    def paramIsPointer(self, param):
-        ispointer = False
-        paramtype = param.find('type')
-        if paramtype.tail is not None and '*' in paramtype.tail:
-            ispointer = True
-
-        return ispointer
-
-    #
-    # Check if the parameter passed in is a static array
-    def paramIsStaticArray(self, param):
-        if param.find('name').tail is not None:
-            if param.find('name').tail[0] == '[':
-                return True
-
-    #
-    # Get the length of a parameter that's been identified as a static array
-    def staticArrayLength(self, param):
-        paramname = param.find('name')
-        paramenumsize = param.find('enum')
-
-        if paramenumsize is not None:
-            return paramenumsize.text
-        else:
-            return paramname.tail[1:-1]
-
-    #
-    # Check if the parameter passed in is a pointer to an array
-    def paramIsArray(self, param):
-        return param.attrib.get('len') is not None
-
-    #
-    # Get the parent of a handle object
-    def getHandleParent(self, typename):
-        types = self.registry.findall("types/type")
-        for elem in types:
-            if (elem.find("name") is not None and elem.find('name').text == typename) or elem.attrib.get('name') == typename:
-                return elem.attrib.get('parent')
-
-    #
-    # Check if a parent object is dispatchable or not
-    def isHandleTypeDispatchable(self, handlename):
-        handle = self.registry.find("types/type/[name='" + handlename + "'][@category='handle']")
-        if handle is not None and handle.find('type').text == 'VK_DEFINE_HANDLE':
-            return True
-        else:
-            return False
-
-    def isHandleOptional(self, param, params):
-
-        # See if the handle is optional
-        isOptional = False
-
-        # Simple, if it's optional, return true
-        if param.attrib.get('optional') is not None:
-            return True
-
-        # If no validity is being generated, it usually means that validity is complex and not absolute, so let's say yes.
-        if param.attrib.get('noautovalidity') is not None:
-            return True
-
-        # If the parameter is an array and we haven't already returned, find out if any of the len parameters are optional
-        if self.paramIsArray(param):
-            lengths = param.attrib.get('len').split(',')
-            for length in lengths:
-                if (length) != 'null-terminated' and (length) != '1':
-                    for otherparam in params:
-                        if otherparam.find('name').text == length:
-                            if otherparam.attrib.get('optional') is not None:
-                                return True
-
-        return False
-    #
-    # Get the category of a type
-    def getTypeCategory(self, typename):
-        types = self.registry.findall("types/type")
-        for elem in types:
-            if (elem.find("name") is not None and elem.find('name').text == typename) or elem.attrib.get('name') == typename:
-                return elem.attrib.get('category')
-
-    #
-    # Make a chunk of text for the end of a parameter if it is an array
-    def makeAsciiDocPreChunk(self, param, params):
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        # General pre-amble. Check optionality and add stuff.
-        asciidoc = '* '
-
-        if self.paramIsStaticArray(param):
-            asciidoc += 'Any given element of '
-
-        elif self.paramIsArray(param):
-            lengths = param.attrib.get('len').split(',')
-
-            # Find all the parameters that are called out as optional, so we can document that they might be zero, and the array may be ignored
-            optionallengths = []
-            for length in lengths:
-                if (length) != 'null-terminated' and (length) != '1':
-                    for otherparam in params:
-                        if otherparam.find('name').text == length:
-                            if otherparam.attrib.get('optional') is not None:
-                                if self.paramIsPointer(otherparam):
-                                    optionallengths.append('the value referenced by ' + self.makeParameterName(length))
-                                else:
-                                    optionallengths.append(self.makeParameterName(length))
-
-            # Document that these arrays may be ignored if any of the length values are 0
-            if len(optionallengths) != 0 or param.attrib.get('optional') is not None:
-                asciidoc += 'If '
-
-
-                if len(optionallengths) != 0:
-                    if len(optionallengths) == 1:
-
-                        asciidoc += optionallengths[0]
-                        asciidoc += ' is '
-
-                    else:
-                        asciidoc += ' or '.join(optionallengths)
-                        asciidoc += ' are '
-
-                    asciidoc += 'not `0`, '
-
-                if len(optionallengths) != 0 and param.attrib.get('optional') is not None:
-                    asciidoc += 'and '
-
-                if param.attrib.get('optional') is not None:
-                    asciidoc += self.makeParameterName(paramname.text)
-                    asciidoc += ' is not `NULL`, '
-
-        elif param.attrib.get('optional') is not None:
-            # Don't generate this stub for bitflags
-            if self.getTypeCategory(paramtype.text) != 'bitmask':
-                if param.attrib.get('optional').split(',')[0] == 'true':
-                    asciidoc += 'If '
-                    asciidoc += self.makeParameterName(paramname.text)
-                    asciidoc += ' is not '
-                    if self.paramIsArray(param) or self.paramIsPointer(param) or self.isHandleTypeDispatchable(paramtype.text):
-                        asciidoc += '`NULL`'
-                    elif self.getTypeCategory(paramtype.text) == 'handle':
-                        asciidoc += 'sname:VK_NULL_HANDLE'
-                    else:
-                        asciidoc += '`0`'
-
-                    asciidoc += ', '
-
-        return asciidoc
-
-    #
-    # Make the generic asciidoc line chunk portion used for all parameters.
-    # May return an empty string if nothing to validate.
-    def createValidationLineForParameterIntroChunk(self, param, params, typetext):
-        asciidoc = ''
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        asciidoc += self.makeAsciiDocPreChunk(param, params)
-
-        asciidoc += self.makeParameterName(paramname.text)
-        asciidoc += ' must: be '
-
-        if self.paramIsArray(param):
-            # Arrays. These are hard to get right, apparently
-
-            lengths = param.attrib.get('len').split(',')
-
-            if (lengths[0]) == 'null-terminated':
-                asciidoc += 'a null-terminated '
-            elif (lengths[0]) == '1':
-                asciidoc += 'a pointer to '
-            else:
-                asciidoc += 'a pointer to an array of '
-
-                # Handle equations, which are currently denoted with latex
-                if 'latexmath:' in lengths[0]:
-                    asciidoc += lengths[0]
-                else:
-                    asciidoc += self.makeParameterName(lengths[0])
-                asciidoc += ' '
-
-            for length in lengths[1:]:
-                if (length) == 'null-terminated': # This should always be the last thing. If it ever isn't for some bizarre reason, then this will need some massaging.
-                    asciidoc += 'null-terminated '
-                elif (length) == '1':
-                    asciidoc += 'pointers to '
-                else:
-                    asciidoc += 'pointers to arrays of '
-                    # Handle equations, which are currently denoted with latex
-                    if 'latex:' in length:
-                        asciidoc += length
-                    else:
-                        asciidoc += self.makeParameterName(length)
-                    asciidoc += ' '
-
-            # Void pointers don't actually point at anything - remove the word "to"
-            if paramtype.text == 'void':
-                if lengths[-1] == '1':
-                    if len(lengths) > 1:
-                        asciidoc = asciidoc[:-5]    # Take care of the extra s added by the post array chunk function. #HACK#
-                    else:
-                        asciidoc = asciidoc[:-4]
-                else:
-                    # An array of void values is a byte array.
-                    asciidoc += 'byte'
-
-            elif paramtype.text == 'char':
-                # A null terminated array of chars is a string
-                if lengths[-1] == 'null-terminated':
-                    asciidoc += 'string'
-                else:
-                    # Else it's just a bunch of chars
-                    asciidoc += 'char value'
-            elif param.text is not None:
-                # If a value is "const" that means it won't get modified, so it must be valid going into the function.
-                if 'const' in param.text:
-                    typecategory = self.getTypeCategory(paramtype.text)
-                    if (typecategory != 'struct' and typecategory != 'union' and typecategory != 'basetype' and typecategory is not None) or not self.isStructAlwaysValid(paramtype.text):
-                        asciidoc += 'valid '
-
-            asciidoc += typetext
-
-            # pluralize
-            if len(lengths) > 1 or (lengths[0] != '1' and lengths[0] != 'null-terminated'):
-                asciidoc += 's'
-
-        elif self.paramIsPointer(param):
-            # Handle pointers - which are really special case arrays (i.e. they don't have a length)
-            pointercount = paramtype.tail.count('*')
-
-            # Could be multi-level pointers (e.g. ppData - pointer to a pointer). Handle that.
-            for i in range(0, pointercount):
-                asciidoc += 'a pointer to '
-
-            if paramtype.text == 'void':
-                # If there's only one pointer, it's optional, and it doesn't point at anything in particular - we don't need any language.
-                if pointercount == 1 and param.attrib.get('optional') is not None:
-                    return '' # early return
-                else:
-                    # Pointer to nothing in particular - delete the " to " portion
-                    asciidoc = asciidoc[:-4]
-            else:
-                # Add an article for English semantic win
-                asciidoc += 'a '
-
-            # If a value is "const" that means it won't get modified, so it must be valid going into the function.
-            if param.text is not None and paramtype.text != 'void':
-                if 'const' in param.text:
-                    asciidoc += 'valid '
-
-            asciidoc += typetext
-
-        else:
-            # Non-pointer, non-optional things must be valid
-            asciidoc += 'a valid '
-            asciidoc += typetext
-
-        if asciidoc != '':
-            asciidoc += '\n'
-
-            # Add additional line for non-optional bitmasks
-            if self.getTypeCategory(paramtype.text) == 'bitmask':
-                if param.attrib.get('optional') is None:
-                    asciidoc += '* '
-                    if self.paramIsArray(param):
-                        asciidoc += 'Each element of '
-                    asciidoc += 'pname:'
-                    asciidoc += paramname.text
-                    asciidoc += ' mustnot: be `0`'
-                    asciidoc += '\n'
-
-        return asciidoc
-
-    def makeAsciiDocLineForParameter(self, param, params, typetext):
-        if param.attrib.get('noautovalidity') is not None:
-            return ''
-        asciidoc  = self.createValidationLineForParameterIntroChunk(param, params, typetext)
-
-        return asciidoc
-
-    # Try to do check if a structure is always considered valid (i.e. there's no rules to its acceptance)
-    def isStructAlwaysValid(self, structname):
-
-        struct = self.registry.find("types/type[@name='" + structname + "']")
-
-        params = struct.findall('member')
-        validity = struct.find('validity')
-
-        if validity is not None:
-            return False
-
-        for param in params:
-            paramname = param.find('name')
-            paramtype = param.find('type')
-            typecategory = self.getTypeCategory(paramtype.text)
-
-            if paramname.text == 'pNext':
-                return False
-
-            if paramname.text == 'sType':
-                return False
-
-            if paramtype.text == 'void' or paramtype.text == 'char' or self.paramIsArray(param) or self.paramIsPointer(param):
-                if self.makeAsciiDocLineForParameter(param, params, '') != '':
-                    return False
-            elif typecategory == 'handle' or typecategory == 'enum' or typecategory == 'bitmask' or param.attrib.get('returnedonly') == 'true':
-                return False
-            elif typecategory == 'struct' or typecategory == 'union':
-                if self.isStructAlwaysValid(paramtype.text) is False:
-                    return False
-
-        return True
-
-    #
-    # Make an entire asciidoc line for a given parameter
-    def createValidationLineForParameter(self, param, params, typecategory):
-        asciidoc = ''
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        if paramtype.text == 'void' or paramtype.text == 'char':
-            # Chars and void are special cases - needs care inside the generator functions
-            # A null-terminated char array is a string, else it's chars.
-            # An array of void values is a byte array, a void pointer is just a pointer to nothing in particular
-            asciidoc += self.makeAsciiDocLineForParameter(param, params, '')
-        elif typecategory == 'bitmask':
-            bitsname = paramtype.text.replace('Flags', 'FlagBits')
-            if self.registry.find("enums[@name='" + bitsname + "']") is None:
-                asciidoc += '* '
-                asciidoc += self.makeParameterName(paramname.text)
-                asciidoc += ' must: be `0`'
-                asciidoc += '\n'
-            else:
-                if self.paramIsArray(param):
-                    asciidoc += self.makeAsciiDocLineForParameter(param, params, 'combinations of ' + self.makeEnumerationName(bitsname) + ' value')
-                else:
-                    asciidoc += self.makeAsciiDocLineForParameter(param, params, 'combination of ' + self.makeEnumerationName(bitsname) + ' values')
-        elif typecategory == 'handle':
-            asciidoc += self.makeAsciiDocLineForParameter(param, params, self.makeStructName(paramtype.text) + ' handle')
-        elif typecategory == 'enum':
-            asciidoc += self.makeAsciiDocLineForParameter(param, params, self.makeEnumerationName(paramtype.text) + ' value')
-        elif typecategory == 'struct':
-            if (self.paramIsArray(param) or self.paramIsPointer(param)) or not self.isStructAlwaysValid(paramtype.text):
-                asciidoc += self.makeAsciiDocLineForParameter(param, params, self.makeStructName(paramtype.text) + ' structure')
-        elif typecategory == 'union':
-            if (self.paramIsArray(param) or self.paramIsPointer(param)) or not self.isStructAlwaysValid(paramtype.text):
-                asciidoc += self.makeAsciiDocLineForParameter(param, params, self.makeStructName(paramtype.text) + ' union')
-        elif self.paramIsArray(param) or self.paramIsPointer(param):
-            asciidoc += self.makeAsciiDocLineForParameter(param, params, self.makeBaseTypeName(paramtype.text) + ' value')
-
-        return asciidoc
-
-    #
-    # Make an asciidoc validity entry for a handle's parent object
-    def makeAsciiDocHandleParent(self, param, params):
-        asciidoc = ''
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        # Deal with handle parents
-        handleparent = self.getHandleParent(paramtype.text)
-        if handleparent is not None:
-            parentreference = None
-            for otherparam in params:
-                if otherparam.find('type').text == handleparent:
-                    parentreference = otherparam.find('name').text
-            if parentreference is not None:
-                asciidoc += '* '
-
-                if self.isHandleOptional(param, params):
-                    if self.paramIsArray(param):
-                        asciidoc += 'Each element of '
-                        asciidoc += self.makeParameterName(paramname.text)
-                        asciidoc += ' that is a valid handle'
-                    else:
-                        asciidoc += 'If '
-                        asciidoc += self.makeParameterName(paramname.text)
-                        asciidoc += ' is a valid handle, it'
-                else:
-                    if self.paramIsArray(param):
-                        asciidoc += 'Each element of '
-                    asciidoc += self.makeParameterName(paramname.text)
-                asciidoc += ' must: have been created, allocated or retrieved from '
-                asciidoc += self.makeParameterName(parentreference)
-
-                asciidoc += '\n'
-        return asciidoc
-
-    #
-    # Generate an asciidoc validity line for the sType value of a struct
-    def makeStructureType(self, blockname, param):
-        asciidoc = '* '
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        asciidoc += self.makeParameterName(paramname.text)
-        asciidoc += ' must: be '
-
-        structuretype = ''
-        for elem in re.findall(r'(([A-Z][a-z]+)|([A-Z][A-Z]+))', blockname):
-            if elem[0] == 'Vk':
-                structuretype += 'VK_STRUCTURE_TYPE_'
-            else:
-                structuretype += elem[0].upper()
-                structuretype += '_'
-
-        asciidoc += self.makeEnumerantName(structuretype[:-1])
-        asciidoc += '\n'
-
-        return asciidoc
-
-    #
-    # Generate an asciidoc validity line for the pNext value of a struct
-    def makeStructureExtensionPointer(self, param):
-        asciidoc = '* '
-        paramname = param.find('name')
-        paramtype = param.find('type')
-
-        asciidoc += self.makeParameterName(paramname.text)
-
-        validextensionstructs = param.attrib.get('validextensionstructs')
-        asciidoc += ' must: be `NULL`'
-        if validextensionstructs is not None:
-            extensionstructs = ['slink:' + x for x in validextensionstructs.split(',')]
-            asciidoc += ', or a pointer to a valid instance of '
-            if len(extensionstructs) == 1:
-                asciidoc += validextensionstructs
-            else:
-                asciidoc += (', ').join(extensionstructs[:-1]) + ' or ' + extensionstructs[-1]
-
-        asciidoc += '\n'
-
-        return asciidoc
-
-    #
-    # Generate all the valid usage information for a given struct or command
-    def makeValidUsageStatements(self, cmd, blockname, params, usages):
-        # Start the asciidoc block for this
-        asciidoc = ''
-
-        handles = []
-        anyparentedhandlesoptional = False
-        parentdictionary = {}
-        arraylengths = set()
-        for param in params:
-            paramname = param.find('name')
-            paramtype = param.find('type')
-
-            # Get the type's category
-            typecategory = self.getTypeCategory(paramtype.text)
-
-            # Generate language to independently validate a parameter
-            if paramtype.text == 'VkStructureType' and paramname.text == 'sType':
-                asciidoc += self.makeStructureType(blockname, param)
-            elif paramtype.text == 'void' and paramname.text == 'pNext':
-                asciidoc += self.makeStructureExtensionPointer(param)
-            else:
-                asciidoc += self.createValidationLineForParameter(param, params, typecategory)
-
-            # Ensure that any parenting is properly validated, and list that a handle was found
-            if typecategory == 'handle':
-                # Don't detect a parent for return values!
-                if not self.paramIsPointer(param) or (param.text is not None and 'const' in param.text):
-                    parent = self.getHandleParent(paramtype.text)
-                    if parent is not None:
-                        handles.append(param)
-
-                        # If any param is optional, it affects the output
-                        if self.isHandleOptional(param, params):
-                            anyparentedhandlesoptional = True
-
-                        # Find the first dispatchable parent
-                        ancestor = parent
-                        while ancestor is not None and not self.isHandleTypeDispatchable(ancestor):
-                            ancestor = self.getHandleParent(ancestor)
-
-                        # If one was found, add this parameter to the parent dictionary
-                        if ancestor is not None:
-                            if ancestor not in parentdictionary:
-                                parentdictionary[ancestor] = []
-
-                            if self.paramIsArray(param):
-                                parentdictionary[ancestor].append('the elements of ' + self.makeParameterName(paramname.text))
-                            else:
-                                parentdictionary[ancestor].append(self.makeParameterName(paramname.text))
-
-            # Get the array length for this parameter
-            arraylength = param.attrib.get('len')
-            if arraylength is not None:
-                for onelength in arraylength.split(','):
-                    arraylengths.add(onelength)
-
-        # For any vkQueue* functions, there might be queue type data
-        if 'vkQueue' in blockname:
-            # The queue type must be valid
-            queuetypes = cmd.attrib.get('queues')
-            if queuetypes is not None:
-                queuebits = []
-                for queuetype in re.findall(r'([^,]+)', queuetypes):
-                    queuebits.append(queuetype.replace('_',' '))
-
-                asciidoc += '* '
-                asciidoc += 'The pname:queue must: support '
-                if len(queuebits) == 1:
-                    asciidoc += queuebits[0]
-                else:
-                    asciidoc += (', ').join(queuebits[:-1])
-                    asciidoc += ' or '
-                    asciidoc += queuebits[-1]
-                asciidoc += ' operations'
-                asciidoc += '\n'
-
-        if 'vkCmd' in blockname:
-            # The commandBuffer parameter must be being recorded
-            asciidoc += '* '
-            asciidoc += 'pname:commandBuffer must: be in the recording state'
-            asciidoc += '\n'
-
-            # The queue type must be valid
-            queuetypes = cmd.attrib.get('queues')
-            queuebits = []
-            for queuetype in re.findall(r'([^,]+)', queuetypes):
-                queuebits.append(queuetype.replace('_',' '))
-
-            asciidoc += '* '
-            asciidoc += 'The sname:VkCommandPool that pname:commandBuffer was allocated from must: support '
-            if len(queuebits) == 1:
-                asciidoc += queuebits[0]
-            else:
-                asciidoc += (', ').join(queuebits[:-1])
-                asciidoc += ' or '
-                asciidoc += queuebits[-1]
-            asciidoc += ' operations'
-            asciidoc += '\n'
-
-            # Must be called inside/outside a renderpass appropriately
-            renderpass = cmd.attrib.get('renderpass')
-
-            if renderpass != 'both':
-                asciidoc += '* This command must: only be called '
-                asciidoc += renderpass
-                asciidoc += ' of a render pass instance'
-                asciidoc += '\n'
-
-            # Must be in the right level command buffer
-            cmdbufferlevel = cmd.attrib.get('cmdbufferlevel')
-
-            if cmdbufferlevel != 'primary,secondary':
-                asciidoc += '* pname:commandBuffer must: be a '
-                asciidoc += cmdbufferlevel
-                asciidoc += ' sname:VkCommandBuffer'
-                asciidoc += '\n'
-
-        # Any non-optional arraylengths should specify they must be greater than 0
-        for param in params:
-            paramname = param.find('name')
-
-            for arraylength in arraylengths:
-                if paramname.text == arraylength and param.attrib.get('optional') is None:
-                    # Get all the array dependencies
-                    arrays = cmd.findall("param/[@len='" + arraylength + "'][@optional='true']")
-
-                    # Get all the optional array dependencies, including those not generating validity for some reason
-                    optionalarrays = cmd.findall("param/[@len='" + arraylength + "'][@optional='true']")
-                    optionalarrays.extend(cmd.findall("param/[@len='" + arraylength + "'][@noautovalidity='true']"))
-
-                    asciidoc += '* '
-
-                    # Allow lengths to be arbitrary if all their dependents are optional
-                    if len(optionalarrays) == len(arrays) and len(optionalarrays) != 0:
-                        asciidoc += 'If '
-                        if len(optionalarrays) > 1:
-                            asciidoc += 'any of '
-
-                        for array in optionalarrays[:-1]:
-                            asciidoc += self.makeParameterName(optionalarrays.find('name').text)
-                            asciidoc += ', '
-
-                        if len(optionalarrays) > 1:
-                            asciidoc += 'and '
-                            asciidoc += self.makeParameterName(optionalarrays[-1].find('name').text)
-                            asciidoc += ' are '
-                        else:
-                            asciidoc += self.makeParameterName(optionalarrays[-1].find('name').text)
-                            asciidoc += ' is '
-
-                        asciidoc += 'not `NULL`, '
-
-                        if self.paramIsPointer(param):
-                            asciidoc += 'the value referenced by '
-
-                    elif self.paramIsPointer(param):
-                        asciidoc += 'The value referenced by '
-
-                    asciidoc += self.makeParameterName(arraylength)
-                    asciidoc += ' must: be greater than `0`'
-                    asciidoc += '\n'
-
-        # Find the parents of all objects referenced in this command
-        for param in handles:
-            asciidoc += self.makeAsciiDocHandleParent(param, params)
-
-        # Find the common ancestors of objects
-        noancestorscount = 0
-        while noancestorscount < len(parentdictionary):
-            noancestorscount = 0
-            oldparentdictionary = parentdictionary.copy()
-            for parent in oldparentdictionary.items():
-                ancestor = self.getHandleParent(parent[0])
-
-                while ancestor is not None and ancestor not in parentdictionary:
-                    ancestor = self.getHandleParent(ancestor)
-
-                if ancestor is not None:
-                    parentdictionary[ancestor] += parentdictionary.pop(parent[0])
-                else:
-                    # No ancestors possible - so count it up
-                    noancestorscount += 1
-
-        # Add validation language about common ancestors
-        for parent in parentdictionary.items():
-            if len(parent[1]) > 1:
-                parentlanguage = '* '
-
-                parentlanguage += 'Each of '
-                parentlanguage += ", ".join(parent[1][:-1])
-                parentlanguage += ' and '
-                parentlanguage += parent[1][-1]
-                if anyparentedhandlesoptional is True:
-                    parentlanguage += ' that are valid handles'
-                parentlanguage += ' must: have been created, allocated or retrieved from the same '
-                parentlanguage += self.makeStructName(parent[0])
-                parentlanguage += '\n'
-
-                # Capitalize and add to the main language
-                asciidoc += parentlanguage
-
-        # Add in any plain-text validation language that should be added
-        for usage in usages:
-            asciidoc += '* '
-            asciidoc += usage
-            asciidoc += '\n'
-
-        # In case there's nothing to report, return None
-        if asciidoc == '':
-            return None
-        # Delimit the asciidoc block
-        return asciidoc
-
-    def makeThreadSafetyBlock(self, cmd, paramtext):
-        """Generate C function pointer typedef for <command> Element"""
-        paramdecl = ''
-
-        # For any vkCmd* functions, the commandBuffer parameter must be being recorded
-        if cmd.find('proto/name') is not None and 'vkCmd' in cmd.find('proto/name'):
-            paramdecl += '* '
-            paramdecl += 'The sname:VkCommandPool that pname:commandBuffer was created from'
-            paramdecl += '\n'
-
-        # Find and add any parameters that are thread unsafe
-        explicitexternsyncparams = cmd.findall(paramtext + "[@externsync]")
-        if (explicitexternsyncparams is not None):
-            for param in explicitexternsyncparams:
-                externsyncattribs = param.attrib.get('externsync')
-                paramname = param.find('name')
-                for externsyncattrib in externsyncattribs.split(','):
-                    paramdecl += '* '
-                    paramdecl += 'Host access to '
-                    if externsyncattrib == 'true':
-                        if self.paramIsArray(param):
-                            paramdecl += 'each member of ' + self.makeParameterName(paramname.text)
-                        elif self.paramIsPointer(param):
-                            paramdecl += 'the object referenced by ' + self.makeParameterName(paramname.text)
-                        else:
-                            paramdecl += self.makeParameterName(paramname.text)
-                    else:
-                        paramdecl += 'pname:'
-                        paramdecl += externsyncattrib
-                    paramdecl += ' must: be externally synchronized\n'
-
-        # Find and add any "implicit" parameters that are thread unsafe
-        implicitexternsyncparams = cmd.find('implicitexternsyncparams')
-        if (implicitexternsyncparams is not None):
-            for elem in implicitexternsyncparams:
-                paramdecl += '* '
-                paramdecl += 'Host access to '
-                paramdecl += elem.text
-                paramdecl += ' must: be externally synchronized\n'
-
-        if (paramdecl == ''):
-            return None
-        else:
-            return paramdecl
-
-    def makeCommandPropertiesTableEntry(self, cmd, name):
-
-        if 'vkCmd' in name:
-            # Must be called inside/outside a renderpass appropriately
-            cmdbufferlevel = cmd.attrib.get('cmdbufferlevel')
-            cmdbufferlevel = (' + \n').join(cmdbufferlevel.title().split(','))
-
-            renderpass = cmd.attrib.get('renderpass')
-            renderpass = renderpass.capitalize()
-
-            queues = cmd.attrib.get('queues')
-            queues = (' + \n').join(queues.upper().split(','))
-
-            return '|' + cmdbufferlevel + '|' + renderpass + '|' + queues
-        elif 'vkQueue' in name:
-            # Must be called inside/outside a renderpass appropriately
-
-            queues = cmd.attrib.get('queues')
-            if queues is None:
-                queues = 'Any'
-            else:
-                queues = (' + \n').join(queues.upper().split(','))
-
-            return '|-|-|' + queues
-
-        return None
-
-    def makeSuccessCodes(self, cmd, name):
-
-        successcodes = cmd.attrib.get('successcodes')
-        if successcodes is not None:
-
-            successcodeentry = ''
-            successcodes = successcodes.split(',')
-            return '* ename:' + '\n* ename:'.join(successcodes)
-
-        return None
-
-    def makeErrorCodes(self, cmd, name):
-
-        errorcodes = cmd.attrib.get('errorcodes')
-        if errorcodes is not None:
-
-            errorcodeentry = ''
-            errorcodes = errorcodes.split(',')
-            return '* ename:' + '\n* ename:'.join(errorcodes)
-
-        return None
-
-    #
-    # Command generation
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        #
-        # Get all the parameters
-        params = cmdinfo.elem.findall('param')
-        usageelements = cmdinfo.elem.findall('validity/usage')
-        usages = []
-
-        for usage in usageelements:
-            usages.append(usage.text)
-        for usage in cmdinfo.additionalValidity:
-            usages.append(usage.text)
-        for usage in cmdinfo.removedValidity:
-            usages.remove(usage.text)
-
-        validity = self.makeValidUsageStatements(cmdinfo.elem, name, params, usages)
-        threadsafety = self.makeThreadSafetyBlock(cmdinfo.elem, 'param')
-        commandpropertiesentry = self.makeCommandPropertiesTableEntry(cmdinfo.elem, name)
-        successcodes = self.makeSuccessCodes(cmdinfo.elem, name)
-        errorcodes = self.makeErrorCodes(cmdinfo.elem, name)
-
-        self.writeInclude('validity/protos', name, validity, threadsafety, commandpropertiesentry, successcodes, errorcodes)
-
-    #
-    # Struct Generation
-    def genStruct(self, typeinfo, typename):
-        OutputGenerator.genStruct(self, typeinfo, typename)
-
-        # Anything that's only ever returned can't be set by the user, so shouldn't have any validity information.
-        if typeinfo.elem.attrib.get('returnedonly') is None:
-            params = typeinfo.elem.findall('member')
-
-            usageelements = typeinfo.elem.findall('validity/usage')
-            usages = []
-
-            for usage in usageelements:
-                usages.append(usage.text)
-            for usage in typeinfo.additionalValidity:
-                usages.append(usage.text)
-            for usage in typeinfo.removedValidity:
-                usages.remove(usage.text)
-
-            validity = self.makeValidUsageStatements(typeinfo.elem, typename, params, usages)
-            threadsafety = self.makeThreadSafetyBlock(typeinfo.elem, 'member')
-
-            self.writeInclude('validity/structs', typename, validity, threadsafety, None, None, None)
-        else:
-            # Still generate files for return only structs, in case this state changes later
-            self.writeInclude('validity/structs', typename, None, None, None, None, None)
-
-    #
-    # Type Generation
-    def genType(self, typeinfo, typename):
-        OutputGenerator.genType(self, typeinfo, typename)
-
-        category = typeinfo.elem.get('category')
-        if (category == 'struct' or category == 'union'):
-            self.genStruct(typeinfo, typename)
-
-# HostSynchronizationOutputGenerator - subclass of OutputGenerator.
-# Generates AsciiDoc includes of the externsync parameter table for the
-# fundamentals chapter of the Vulkan specification. Similar to
-# DocOutputGenerator.
-#
-# ---- methods ----
-# HostSynchronizationOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# genCmd(cmdinfo)
-class HostSynchronizationOutputGenerator(OutputGenerator):
-    # Generate Host Synchronized Parameters in a table at the top of the spec
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-
-    threadsafety = {'parameters': '', 'parameterlists': '', 'implicit': ''}
-
-    def makeParameterName(self, name):
-        return 'pname:' + name
-
-    def makeFLink(self, name):
-        return 'flink:' + name
-
-    #
-    # Generate an include file
-    #
-    # directory - subdirectory to put file in
-    # basename - base name of the file
-    # contents - contents of the file (Asciidoc boilerplate aside)
-    def writeInclude(self):
-
-        if self.threadsafety['parameters'] is not None:
-            # Create file
-            filename = self.genOpts.genDirectory + '/' + self.genOpts.filename + '/parameters.txt'
-            self.logMsg('diag', '# Generating include file:', filename)
-            fp = open(filename, 'w')
-
-            # Host Synchronization
-            write('// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry', file=fp)
-            write('.Externally Synchronized Parameters', file=fp)
-            write('*' * 80, file=fp)
-            write(self.threadsafety['parameters'], file=fp, end='')
-            write('*' * 80, file=fp)
-            write('', file=fp)
-
-        if self.threadsafety['parameterlists'] is not None:
-            # Create file
-            filename = self.genOpts.genDirectory + '/' + self.genOpts.filename + '/parameterlists.txt'
-            self.logMsg('diag', '# Generating include file:', filename)
-            fp = open(filename, 'w')
-
-            # Host Synchronization
-            write('// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry', file=fp)
-            write('.Externally Synchronized Parameter Lists', file=fp)
-            write('*' * 80, file=fp)
-            write(self.threadsafety['parameterlists'], file=fp, end='')
-            write('*' * 80, file=fp)
-            write('', file=fp)
-
-        if self.threadsafety['implicit'] is not None:
-            # Create file
-            filename = self.genOpts.genDirectory + '/' + self.genOpts.filename + '/implicit.txt'
-            self.logMsg('diag', '# Generating include file:', filename)
-            fp = open(filename, 'w')
-
-            # Host Synchronization
-            write('// WARNING: DO NOT MODIFY! This file is automatically generated from the vk.xml registry', file=fp)
-            write('.Implicit Externally Synchronized Parameters', file=fp)
-            write('*' * 80, file=fp)
-            write(self.threadsafety['implicit'], file=fp, end='')
-            write('*' * 80, file=fp)
-            write('', file=fp)
-
-        fp.close()
-
-    #
-    # Check if the parameter passed in is a pointer to an array
-    def paramIsArray(self, param):
-        return param.attrib.get('len') is not None
-
-    # Check if the parameter passed in is a pointer
-    def paramIsPointer(self, param):
-        ispointer = False
-        paramtype = param.find('type')
-        if paramtype.tail is not None and '*' in paramtype.tail:
-            ispointer = True
-
-        return ispointer
-
-    # Turn the "name[].member[]" notation into plain English.
-    def makeThreadDereferenceHumanReadable(self, dereference):
-        matches = re.findall(r"[\w]+[^\w]*",dereference)
-        stringval = ''
-        for match in reversed(matches):
-            if '->' in match or '.' in match:
-                stringval += 'member of '
-            if '[]' in match:
-                stringval += 'each element of '
-
-            stringval += 'the '
-            stringval += self.makeParameterName(re.findall(r"[\w]+",match)[0])
-            stringval += ' '
-
-        stringval += 'parameter'
-
-        return stringval[0].upper() + stringval[1:]
-
-    def makeThreadSafetyBlocks(self, cmd, paramtext):
-        protoname = cmd.find('proto/name').text
-
-        # Find and add any parameters that are thread unsafe
-        explicitexternsyncparams = cmd.findall(paramtext + "[@externsync]")
-        if (explicitexternsyncparams is not None):
-            for param in explicitexternsyncparams:
-                externsyncattribs = param.attrib.get('externsync')
-                paramname = param.find('name')
-                for externsyncattrib in externsyncattribs.split(','):
-
-                    tempstring = '* '
-                    if externsyncattrib == 'true':
-                        if self.paramIsArray(param):
-                            tempstring += 'Each element of the '
-                        elif self.paramIsPointer(param):
-                            tempstring += 'The object referenced by the '
-                        else:
-                            tempstring += 'The '
-
-                        tempstring += self.makeParameterName(paramname.text)
-                        tempstring += ' parameter'
-
-                    else:
-                        tempstring += self.makeThreadDereferenceHumanReadable(externsyncattrib)
-
-                    tempstring += ' in '
-                    tempstring += self.makeFLink(protoname)
-                    tempstring += '\n'
-
-
-                    if ' element of ' in tempstring:
-                        self.threadsafety['parameterlists'] += tempstring
-                    else:
-                        self.threadsafety['parameters'] += tempstring
-
-
-        # Find and add any "implicit" parameters that are thread unsafe
-        implicitexternsyncparams = cmd.find('implicitexternsyncparams')
-        if (implicitexternsyncparams is not None):
-            for elem in implicitexternsyncparams:
-                self.threadsafety['implicit'] += '* '
-                self.threadsafety['implicit'] += elem.text[0].upper()
-                self.threadsafety['implicit'] += elem.text[1:]
-                self.threadsafety['implicit'] += ' in '
-                self.threadsafety['implicit'] += self.makeFLink(protoname)
-                self.threadsafety['implicit'] += '\n'
-
-
-        # For any vkCmd* functions, the commandBuffer parameter must be being recorded
-        if protoname is not None and 'vkCmd' in protoname:
-            self.threadsafety['implicit'] += '* '
-            self.threadsafety['implicit'] += 'The sname:VkCommandPool that pname:commandBuffer was allocated from, in '
-            self.threadsafety['implicit'] += self.makeFLink(protoname)
-
-            self.threadsafety['implicit'] += '\n'
-
-    #
-    # Command generation
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        #
-        # Get all thh parameters
-        params = cmdinfo.elem.findall('param')
-        usages = cmdinfo.elem.findall('validity/usage')
-
-        self.makeThreadSafetyBlocks(cmdinfo.elem, 'param')
-
-        self.writeInclude()
-
-# ThreadOutputGenerator - subclass of OutputGenerator.
-# Generates Thread checking framework
-#
-# ---- methods ----
-# ThreadOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# beginFeature(interface, emit)
-# endFeature()
-# genType(typeinfo,name)
-# genStruct(typeinfo,name)
-# genGroup(groupinfo,name)
-# genEnum(enuminfo, name)
-# genCmd(cmdinfo)
-class ThreadOutputGenerator(OutputGenerator):
-    """Generate specified API interfaces in a specific style, such as a C header"""
-    # This is an ordered list of sections in the header file.
-    TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
-                     'group', 'bitmask', 'funcpointer', 'struct']
-    ALL_SECTIONS = TYPE_SECTIONS + ['command']
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-        # Internal state - accumulators for different inner block text
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-        self.intercepts = []
-
-    # Check if the parameter passed in is a pointer to an array
-    def paramIsArray(self, param):
-        return param.attrib.get('len') is not None
-
-    # Check if the parameter passed in is a pointer
-    def paramIsPointer(self, param):
-        ispointer = False
-        for elem in param:
-            #write('paramIsPointer '+elem.text, file=sys.stderr)
-            #write('elem.tag '+elem.tag, file=sys.stderr)
-            #if (elem.tail is None):
-            #    write('elem.tail is None', file=sys.stderr)
-            #else:
-            #    write('elem.tail '+elem.tail, file=sys.stderr)
-            if ((elem.tag is not 'type') and (elem.tail is not None)) and '*' in elem.tail:
-                ispointer = True
-            #    write('is pointer', file=sys.stderr)
-        return ispointer
-    def makeThreadUseBlock(self, cmd, functionprefix):
-        """Generate C function pointer typedef for <command> Element"""
-        paramdecl = ''
-        thread_check_dispatchable_objects = [
-            "VkCommandBuffer",
-            "VkDevice",
-            "VkInstance",
-            "VkQueue",
-        ]
-        thread_check_nondispatchable_objects = [
-            "VkBuffer",
-            "VkBufferView",
-            "VkCommandPool",
-            "VkDescriptorPool",
-            "VkDescriptorSetLayout",
-            "VkDeviceMemory",
-            "VkEvent",
-            "VkFence",
-            "VkFramebuffer",
-            "VkImage",
-            "VkImageView",
-            "VkPipeline",
-            "VkPipelineCache",
-            "VkPipelineLayout",
-            "VkQueryPool",
-            "VkRenderPass",
-            "VkSampler",
-            "VkSemaphore",
-            "VkShaderModule",
-        ]
-
-        # Find and add any parameters that are thread unsafe
-        params = cmd.findall('param')
-        for param in params:
-            paramname = param.find('name')
-            if False: # self.paramIsPointer(param):
-                paramdecl += '    // not watching use of pointer ' + paramname.text + '\n'
-            else:
-                externsync = param.attrib.get('externsync')
-                if externsync == 'true':
-                    if self.paramIsArray(param):
-                        paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
-                        paramdecl += '        ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + '[index]);\n'
-                        paramdecl += '    }\n'
-                    else:
-                        paramdecl += '    ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + ');\n'
-                elif (param.attrib.get('externsync')):
-                    if self.paramIsArray(param):
-                        # Externsync can list pointers to arrays of members to synchronize
-                        paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
-                        for member in externsync.split(","):
-                            # Replace first empty [] in member name with index
-                            element = member.replace('[]','[index]',1)
-                            if '[]' in element:
-                                # Replace any second empty [] in element name with
-                                # inner array index based on mapping array names like
-                                # "pSomeThings[]" to "someThingCount" array size.
-                                # This could be more robust by mapping a param member
-                                # name to a struct type and "len" attribute.
-                                limit = element[0:element.find('s[]')] + 'Count'
-                                dotp = limit.rfind('.p')
-                                limit = limit[0:dotp+1] + limit[dotp+2:dotp+3].lower() + limit[dotp+3:]
-                                paramdecl += '        for(uint32_t index2=0;index2<'+limit+';index2++)\n'
-                                element = element.replace('[]','[index2]')
-                            paramdecl += '            ' + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
-                        paramdecl += '    }\n'
-                    else:
-                        # externsync can list members to synchronize
-                        for member in externsync.split(","):
-                            paramdecl += '    ' + functionprefix + 'WriteObject(my_data, ' + member + ');\n'
-                else:
-                    paramtype = param.find('type')
-                    if paramtype is not None:
-                        paramtype = paramtype.text
-                    else:
-                        paramtype = 'None'
-                    if paramtype in thread_check_dispatchable_objects or paramtype in thread_check_nondispatchable_objects:
-                        if self.paramIsArray(param) and ('pPipelines' != paramname.text):
-                            paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
-                            paramdecl += '        ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + '[index]);\n'
-                            paramdecl += '    }\n'
-                        elif not self.paramIsPointer(param):
-                            # Pointer params are often being created.
-                            # They are not being read from.
-                            paramdecl += '    ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + ');\n'
-        explicitexternsyncparams = cmd.findall("param[@externsync]")
-        if (explicitexternsyncparams is not None):
-            for param in explicitexternsyncparams:
-                externsyncattrib = param.attrib.get('externsync')
-                paramname = param.find('name')
-                paramdecl += '    // Host access to '
-                if externsyncattrib == 'true':
-                    if self.paramIsArray(param):
-                        paramdecl += 'each member of ' + paramname.text
-                    elif self.paramIsPointer(param):
-                        paramdecl += 'the object referenced by ' + paramname.text
-                    else:
-                        paramdecl += paramname.text
-                else:
-                    paramdecl += externsyncattrib
-                paramdecl += ' must be externally synchronized\n'
-
-        # Find and add any "implicit" parameters that are thread unsafe
-        implicitexternsyncparams = cmd.find('implicitexternsyncparams')
-        if (implicitexternsyncparams is not None):
-            for elem in implicitexternsyncparams:
-                paramdecl += '    // '
-                paramdecl += elem.text
-                paramdecl += ' must be externally synchronized between host accesses\n'
-
-        if (paramdecl == ''):
-            return None
-        else:
-            return paramdecl
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        # C-specific
-        #
-        # Multiple inclusion protection & C++ namespace.
-        if (genOpts.protectFile and self.genOpts.filename):
-            headerSym = '__' + re.sub('\.h', '_h_', os.path.basename(self.genOpts.filename))
-            write('#ifndef', headerSym, file=self.outFile)
-            write('#define', headerSym, '1', file=self.outFile)
-            self.newline()
-        write('namespace threading {', file=self.outFile)
-        self.newline()
-        #
-        # User-supplied prefix text, if any (list of strings)
-        if (genOpts.prefixText):
-            for s in genOpts.prefixText:
-                write(s, file=self.outFile)
-    def endFile(self):
-        # C-specific
-        # Finish C++ namespace and multiple inclusion protection
-        self.newline()
-        # record intercepted procedures
-        write('// intercepts', file=self.outFile)
-        write('struct { const char* name; PFN_vkVoidFunction pFunc;} procmap[] = {', file=self.outFile)
-        write('\n'.join(self.intercepts), file=self.outFile)
-        write('};\n', file=self.outFile)
-        self.newline()
-        write('} // namespace threading', file=self.outFile)
-        if (self.genOpts.protectFile and self.genOpts.filename):
-            self.newline()
-            write('#endif', file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-    def beginFeature(self, interface, emit):
-        #write('// starting beginFeature', file=self.outFile)
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-        # C-specific
-        # Accumulate includes, defines, types, enums, function pointer typedefs,
-        # end function prototypes separately for this feature. They're only
-        # printed in endFeature().
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-        #write('// ending beginFeature', file=self.outFile)
-    def endFeature(self):
-        # C-specific
-        # Actually write the interface to the output file.
-        #write('// starting endFeature', file=self.outFile)
-        if (self.emit):
-            self.newline()
-            if (self.genOpts.protectFeature):
-                write('#ifndef', self.featureName, file=self.outFile)
-            # If type declarations are needed by other features based on
-            # this one, it may be necessary to suppress the ExtraProtect,
-            # or move it below the 'for section...' loop.
-            #write('// endFeature looking at self.featureExtraProtect', file=self.outFile)
-            if (self.featureExtraProtect != None):
-                write('#ifdef', self.featureExtraProtect, file=self.outFile)
-            #write('#define', self.featureName, '1', file=self.outFile)
-            for section in self.TYPE_SECTIONS:
-                #write('// endFeature writing section'+section, file=self.outFile)
-                contents = self.sections[section]
-                if contents:
-                    write('\n'.join(contents), file=self.outFile)
-                    self.newline()
-            #write('// endFeature looking at self.sections[command]', file=self.outFile)
-            if (self.sections['command']):
-                write('\n'.join(self.sections['command']), end='', file=self.outFile)
-                self.newline()
-            if (self.featureExtraProtect != None):
-                write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
-            if (self.genOpts.protectFeature):
-                write('#endif /*', self.featureName, '*/', file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-        #write('// ending endFeature', file=self.outFile)
-    #
-    # Append a definition to the specified section
-    def appendSection(self, section, text):
-        # self.sections[section].append('SECTION: ' + section + '\n')
-        self.sections[section].append(text)
-    #
-    # Type generation
-    def genType(self, typeinfo, name):
-        pass
-    #
-    # Struct (e.g. C "struct" type) generation.
-    # This is a special case of the <type> tag where the contents are
-    # interpreted as a set of <member> tags instead of freeform C
-    # C type declarations. The <member> tags are just like <param>
-    # tags - they are a declaration of a struct or union member.
-    # Only simple member declarations are supported (no nested
-    # structs etc.)
-    def genStruct(self, typeinfo, typeName):
-        OutputGenerator.genStruct(self, typeinfo, typeName)
-        body = 'typedef ' + typeinfo.elem.get('category') + ' ' + typeName + ' {\n'
-        # paramdecl = self.makeCParamDecl(typeinfo.elem, self.genOpts.alignFuncParam)
-        for member in typeinfo.elem.findall('.//member'):
-            body += self.makeCParamDecl(member, self.genOpts.alignFuncParam)
-            body += ';\n'
-        body += '} ' + typeName + ';\n'
-        self.appendSection('struct', body)
-    #
-    # Group (e.g. C "enum" type) generation.
-    # These are concatenated together with other types.
-    def genGroup(self, groupinfo, groupName):
-        pass
-    # Enumerant generation
-    # <enum> tags may specify their values in several ways, but are usually
-    # just integers.
-    def genEnum(self, enuminfo, name):
-        pass
-    #
-    # Command generation
-    def genCmd(self, cmdinfo, name):
-        # Commands shadowed by interface functions and are not implemented
-        interface_functions = [
-            'vkEnumerateInstanceLayerProperties',
-            'vkEnumerateInstanceExtensionProperties',
-            'vkEnumerateDeviceLayerProperties',
-        ]
-        if name in interface_functions:
-            return
-        special_functions = [
-            'vkGetDeviceProcAddr',
-            'vkGetInstanceProcAddr',
-            'vkCreateDevice',
-            'vkDestroyDevice',
-            'vkCreateInstance',
-            'vkDestroyInstance',
-            'vkAllocateCommandBuffers',
-            'vkFreeCommandBuffers',
-            'vkCreateDebugReportCallbackEXT',
-            'vkDestroyDebugReportCallbackEXT',
-        ]
-        if name in special_functions:
-            decls = self.makeCDecls(cmdinfo.elem)
-            self.appendSection('command', '')
-            self.appendSection('command', '// declare only')
-            self.appendSection('command', decls[0])
-            self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
-            return
-        if "KHR" in name:
-            self.appendSection('command', '// TODO - not wrapping KHR function ' + name)
-            return
-        if ("DebugMarker" in name) and ("EXT" in name):
-            self.appendSection('command', '// TODO - not wrapping EXT function ' + name)
-            return
-        # Determine first if this function needs to be intercepted
-        startthreadsafety = self.makeThreadUseBlock(cmdinfo.elem, 'start')
-        if startthreadsafety is None:
-            return
-        finishthreadsafety = self.makeThreadUseBlock(cmdinfo.elem, 'finish')
-        # record that the function will be intercepted
-        if (self.featureExtraProtect != None):
-            self.intercepts += [ '#ifdef %s' % self.featureExtraProtect ]
-        self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
-        if (self.featureExtraProtect != None):
-            self.intercepts += [ '#endif' ]
-
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        #
-        decls = self.makeCDecls(cmdinfo.elem)
-        self.appendSection('command', '')
-        self.appendSection('command', decls[0][:-1])
-        self.appendSection('command', '{')
-        # setup common to call wrappers
-        # first parameter is always dispatchable
-        dispatchable_type = cmdinfo.elem.find('param/type').text
-        dispatchable_name = cmdinfo.elem.find('param/name').text
-        self.appendSection('command', '    dispatch_key key = get_dispatch_key('+dispatchable_name+');')
-        self.appendSection('command', '    layer_data *my_data = get_my_data_ptr(key, layer_data_map);')
-        if dispatchable_type in ["VkPhysicalDevice", "VkInstance"]:
-            self.appendSection('command', '    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;')
-        else:
-            self.appendSection('command', '    VkLayerDispatchTable *pTable = my_data->device_dispatch_table;')
-        # Declare result variable, if any.
-        resulttype = cmdinfo.elem.find('proto/type')
-        if (resulttype != None and resulttype.text == 'void'):
-          resulttype = None
-        if (resulttype != None):
-            self.appendSection('command', '    ' + resulttype.text + ' result;')
-            assignresult = 'result = '
-        else:
-            assignresult = ''
-
-        self.appendSection('command', '    bool threadChecks = startMultiThread();')
-        self.appendSection('command', '    if (threadChecks) {')
-        self.appendSection('command', "    "+"\n    ".join(str(startthreadsafety).rstrip().split("\n")))
-        self.appendSection('command', '    }')
-        params = cmdinfo.elem.findall('param/name')
-        paramstext = ','.join([str(param.text) for param in params])
-        API = cmdinfo.elem.attrib.get('name').replace('vk','pTable->',1)
-        self.appendSection('command', '    ' + assignresult + API + '(' + paramstext + ');')
-        self.appendSection('command', '    if (threadChecks) {')
-        self.appendSection('command', "    "+"\n    ".join(str(finishthreadsafety).rstrip().split("\n")))
-        self.appendSection('command', '    } else {')
-        self.appendSection('command', '        finishMultiThread();')
-        self.appendSection('command', '    }')
-        # Return result variable, if any.
-        if (resulttype != None):
-            self.appendSection('command', '    return result;')
-        self.appendSection('command', '}')
-    #
-    # override makeProtoName to drop the "vk" prefix
-    def makeProtoName(self, name, tail):
-        return self.genOpts.apientry + name[2:] + tail
-
-# ParamCheckerOutputGenerator - subclass of OutputGenerator.
-# Generates param checker layer code.
-#
-# ---- methods ----
-# ParamCheckerOutputGenerator(errFile, warnFile, diagFile) - args as for
-#   OutputGenerator. Defines additional internal state.
-# ---- methods overriding base class ----
-# beginFile(genOpts)
-# endFile()
-# beginFeature(interface, emit)
-# endFeature()
-# genType(typeinfo,name)
-# genStruct(typeinfo,name)
-# genGroup(groupinfo,name)
-# genEnum(enuminfo, name)
-# genCmd(cmdinfo)
-class ParamCheckerOutputGenerator(OutputGenerator):
-    """Generate ParamChecker code based on XML element attributes"""
-    # This is an ordered list of sections in the header file.
-    ALL_SECTIONS = ['command']
-    def __init__(self,
-                 errFile = sys.stderr,
-                 warnFile = sys.stderr,
-                 diagFile = sys.stdout):
-        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
-        self.INDENT_SPACES = 4
-        # Commands to ignore
-        self.blacklist = [
-            'vkGetInstanceProcAddr',
-            'vkGetDeviceProcAddr',
-            'vkEnumerateInstanceLayerProperties',
-            'vkEnumerateInstanceExtensionsProperties',
-            'vkEnumerateDeviceLayerProperties',
-            'vkEnumerateDeviceExtensionsProperties',
-            'vkCreateDebugReportCallbackEXT',
-            'vkDebugReportMessageEXT']
-        # Validation conditions for some special case struct members that are conditionally validated
-        self.structMemberValidationConditions = { 'VkPipelineColorBlendStateCreateInfo' : { 'logicOp' : '{}logicOpEnable == VK_TRUE' } }
-        # Header version
-        self.headerVersion = None
-        # Internal state - accumulators for different inner block text
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-        self.structNames = []                             # List of Vulkan struct typenames
-        self.stypes = []                                  # Values from the VkStructureType enumeration
-        self.structTypes = dict()                         # Map of Vulkan struct typename to required VkStructureType
-        self.handleTypes = set()                          # Set of handle type names
-        self.commands = []                                # List of CommandData records for all Vulkan commands
-        self.structMembers = []                           # List of StructMemberData records for all Vulkan structs
-        self.validatedStructs = dict()                    # Map of structs type names to generated validation code for that struct type
-        self.enumRanges = dict()                          # Map of enum name to BEGIN/END range values
-        self.flags = set()                                # Map of flags typenames
-        self.flagBits = dict()                            # Map of flag bits typename to list of values
-        # Named tuples to store struct and command data
-        self.StructType = namedtuple('StructType', ['name', 'value'])
-        self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isstaticarray', 'isbool', 'israngedenum',
-                                                        'isconst', 'isoptional', 'iscount', 'noautovalidity', 'len', 'extstructs',
-                                                        'condition', 'cdecl'])
-        self.CommandData = namedtuple('CommandData', ['name', 'params', 'cdecl'])
-        self.StructMemberData = namedtuple('StructMemberData', ['name', 'members'])
-    #
-    def incIndent(self, indent):
-        inc = ' ' * self.INDENT_SPACES
-        if indent:
-            return indent + inc
-        return inc
-    #
-    def decIndent(self, indent):
-        if indent and (len(indent) > self.INDENT_SPACES):
-            return indent[:-self.INDENT_SPACES]
-        return ''
-    #
-    def beginFile(self, genOpts):
-        OutputGenerator.beginFile(self, genOpts)
-        # C-specific
-        #
-        # User-supplied prefix text, if any (list of strings)
-        if (genOpts.prefixText):
-            for s in genOpts.prefixText:
-                write(s, file=self.outFile)
-        #
-        # Multiple inclusion protection & C++ wrappers.
-        if (genOpts.protectFile and self.genOpts.filename):
-            headerSym = re.sub('\.h', '_H', os.path.basename(self.genOpts.filename)).upper()
-            write('#ifndef', headerSym, file=self.outFile)
-            write('#define', headerSym, '1', file=self.outFile)
-            self.newline()
-        #
-        # Headers
-        write('#include <string>', file=self.outFile)
-        self.newline()
-        write('#include "vulkan/vulkan.h"', file=self.outFile)
-        write('#include "vk_layer_extension_utils.h"', file=self.outFile)
-        write('#include "parameter_validation_utils.h"', file=self.outFile)
-        #
-        # Macros
-        self.newline()
-        write('#ifndef UNUSED_PARAMETER', file=self.outFile)
-        write('#define UNUSED_PARAMETER(x) (void)(x)', file=self.outFile)
-        write('#endif // UNUSED_PARAMETER', file=self.outFile)
-        #
-        # Namespace
-        self.newline()
-        write('namespace parameter_validation {', file = self.outFile)
-    def endFile(self):
-        # C-specific
-        self.newline()
-        # Namespace
-        write('} // namespace parameter_validation', file = self.outFile)
-        # Finish C++ wrapper and multiple inclusion protection
-        if (self.genOpts.protectFile and self.genOpts.filename):
-            self.newline()
-            write('#endif', file=self.outFile)
-        # Finish processing in superclass
-        OutputGenerator.endFile(self)
-    def beginFeature(self, interface, emit):
-        # Start processing in superclass
-        OutputGenerator.beginFeature(self, interface, emit)
-        # C-specific
-        # Accumulate includes, defines, types, enums, function pointer typedefs,
-        # end function prototypes separately for this feature. They're only
-        # printed in endFeature().
-        self.headerVersion = None
-        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
-        self.structNames = []
-        self.stypes = []
-        self.structTypes = dict()
-        self.handleTypes = set()
-        self.commands = []
-        self.structMembers = []
-        self.validatedStructs = dict()
-        self.enumRanges = dict()
-        self.flags = set()
-        self.flagBits = dict()
-    def endFeature(self):
-        # C-specific
-        # Actually write the interface to the output file.
-        if (self.emit):
-            self.newline()
-            # If type declarations are needed by other features based on
-            # this one, it may be necessary to suppress the ExtraProtect,
-            # or move it below the 'for section...' loop.
-            if (self.featureExtraProtect != None):
-                write('#ifdef', self.featureExtraProtect, file=self.outFile)
-            # Generate the struct member checking code from the captured data
-            self.processStructMemberData()
-            # Generate the command parameter checking code from the captured data
-            self.processCmdData()
-            # Write the declaration for the HeaderVersion
-            if self.headerVersion:
-                write('const uint32_t GeneratedHeaderVersion = {};'.format(self.headerVersion), file=self.outFile)
-                self.newline()
-            # Write the declarations for the VkFlags values combining all flag bits
-            for flag in sorted(self.flags):
-                flagBits = flag.replace('Flags', 'FlagBits')
-                if flagBits in self.flagBits:
-                    bits = self.flagBits[flagBits]
-                    decl = 'const {} All{} = {}'.format(flag, flagBits, bits[0])
-                    for bit in bits[1:]:
-                        decl += '|' + bit
-                    decl += ';'
-                    write(decl, file=self.outFile)
-            self.newline()
-            # Write the parameter validation code to the file
-            if (self.sections['command']):
-                if (self.genOpts.protectProto):
-                    write(self.genOpts.protectProto,
-                          self.genOpts.protectProtoStr, file=self.outFile)
-                write('\n'.join(self.sections['command']), end='', file=self.outFile)
-            if (self.featureExtraProtect != None):
-                write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
-            else:
-                self.newline()
-        # Finish processing in superclass
-        OutputGenerator.endFeature(self)
-    #
-    # Append a definition to the specified section
-    def appendSection(self, section, text):
-        # self.sections[section].append('SECTION: ' + section + '\n')
-        self.sections[section].append(text)
-    #
-    # Type generation
-    def genType(self, typeinfo, name):
-        OutputGenerator.genType(self, typeinfo, name)
-        typeElem = typeinfo.elem
-        # If the type is a struct type, traverse the imbedded <member> tags
-        # generating a structure. Otherwise, emit the tag text.
-        category = typeElem.get('category')
-        if (category == 'struct' or category == 'union'):
-            self.structNames.append(name)
-            self.genStruct(typeinfo, name)
-        elif (category == 'handle'):
-            self.handleTypes.add(name)
-        elif (category == 'bitmask'):
-            self.flags.add(name)
-        elif (category == 'define'):
-            if name == 'VK_HEADER_VERSION':
-                nameElem = typeElem.find('name')
-                self.headerVersion = noneStr(nameElem.tail).strip()
-    #
-    # Struct parameter check generation.
-    # This is a special case of the <type> tag where the contents are
-    # interpreted as a set of <member> tags instead of freeform C
-    # C type declarations. The <member> tags are just like <param>
-    # tags - they are a declaration of a struct or union member.
-    # Only simple member declarations are supported (no nested
-    # structs etc.)
-    def genStruct(self, typeinfo, typeName):
-        OutputGenerator.genStruct(self, typeinfo, typeName)
-        conditions = self.structMemberValidationConditions[typeName] if typeName in self.structMemberValidationConditions else None
-        members = typeinfo.elem.findall('.//member')
-        #
-        # Iterate over members once to get length parameters for arrays
-        lens = set()
-        for member in members:
-            len = self.getLen(member)
-            if len:
-                lens.add(len)
-        #
-        # Generate member info
-        membersInfo = []
-        for member in members:
-            # Get the member's type and name
-            info = self.getTypeNameTuple(member)
-            type = info[0]
-            name = info[1]
-            stypeValue = ''
-            cdecl = self.makeCParamDecl(member, 0)
-            # Process VkStructureType
-            if type == 'VkStructureType':
-                # Extract the required struct type value from the comments
-                # embedded in the original text defining the 'typeinfo' element
-                rawXml = etree.tostring(typeinfo.elem).decode('ascii')
-                result = re.search(r'VK_STRUCTURE_TYPE_\w+', rawXml)
-                if result:
-                    value = result.group(0)
-                else:
-                    value = self.genVkStructureType(typeName)
-                # Store the required type value
-                self.structTypes[typeName] = self.StructType(name=name, value=value)
-            #
-            # Store pointer/array/string info
-            # Check for parameter name in lens set
-            iscount = False
-            if name in lens:
-                iscount = True
-            # The pNext members are not tagged as optional, but are treated as
-            # optional for parameter NULL checks.  Static array members
-            # are also treated as optional to skip NULL pointer validation, as
-            # they won't be NULL.
-            isstaticarray = self.paramIsStaticArray(member)
-            isoptional = False
-            if self.paramIsOptional(member) or (name == 'pNext') or (isstaticarray):
-                isoptional = True
-            membersInfo.append(self.CommandParam(type=type, name=name,
-                                                ispointer=self.paramIsPointer(member),
-                                                isstaticarray=isstaticarray,
-                                                isbool=True if type == 'VkBool32' else False,
-                                                israngedenum=True if type in self.enumRanges else False,
-                                                isconst=True if 'const' in cdecl else False,
-                                                isoptional=isoptional,
-                                                iscount=iscount,
-                                                noautovalidity=True if member.attrib.get('noautovalidity') is not None else False,
-                                                len=self.getLen(member),
-                                                extstructs=member.attrib.get('validextensionstructs') if name == 'pNext' else None,
-                                                condition=conditions[name] if conditions and name in conditions else None,
-                                                cdecl=cdecl))
-        self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo))
-    #
-    # Capture group (e.g. C "enum" type) info to be used for
-    # param check code generation.
-    # These are concatenated together with other types.
-    def genGroup(self, groupinfo, groupName):
-        OutputGenerator.genGroup(self, groupinfo, groupName)
-        groupElem = groupinfo.elem
-        #
-        # Store the sType values
-        if groupName == 'VkStructureType':
-            for elem in groupElem.findall('enum'):
-                self.stypes.append(elem.get('name'))
-        elif 'FlagBits' in groupName:
-            bits = []
-            for elem in groupElem.findall('enum'):
-                bits.append(elem.get('name'))
-            if bits:
-                self.flagBits[groupName] = bits
-        else:
-            # Determine if begin/end ranges are needed (we don't do this for VkStructureType, which has a more finely grained check)
-            expandName = re.sub(r'([0-9a-z_])([A-Z0-9][^A-Z0-9]?)',r'\1_\2',groupName).upper()
-            expandPrefix = expandName
-            expandSuffix = ''
-            expandSuffixMatch = re.search(r'[A-Z][A-Z]+$',groupName)
-            if expandSuffixMatch:
-                expandSuffix = '_' + expandSuffixMatch.group()
-                # Strip off the suffix from the prefix
-                expandPrefix = expandName.rsplit(expandSuffix, 1)[0]
-            isEnum = ('FLAG_BITS' not in expandPrefix)
-            if isEnum:
-                self.enumRanges[groupName] = (expandPrefix + '_BEGIN_RANGE' + expandSuffix, expandPrefix + '_END_RANGE' + expandSuffix)
-    #
-    # Capture command parameter info to be used for param
-    # check code generation.
-    def genCmd(self, cmdinfo, name):
-        OutputGenerator.genCmd(self, cmdinfo, name)
-        if name not in self.blacklist:
-            params = cmdinfo.elem.findall('param')
-            # Get list of array lengths
-            lens = set()
-            for param in params:
-                len = self.getLen(param)
-                if len:
-                    lens.add(len)
-            # Get param info
-            paramsInfo = []
-            for param in params:
-                paramInfo = self.getTypeNameTuple(param)
-                cdecl = self.makeCParamDecl(param, 0)
-                # Check for parameter name in lens set
-                iscount = False
-                if paramInfo[1] in lens:
-                    iscount = True
-                paramsInfo.append(self.CommandParam(type=paramInfo[0], name=paramInfo[1],
-                                                    ispointer=self.paramIsPointer(param),
-                                                    isstaticarray=self.paramIsStaticArray(param),
-                                                    isbool=True if paramInfo[0] == 'VkBool32' else False,
-                                                    israngedenum=True if paramInfo[0] in self.enumRanges else False,
-                                                    isconst=True if 'const' in cdecl else False,
-                                                    isoptional=self.paramIsOptional(param),
-                                                    iscount=iscount,
-                                                    noautovalidity=True if param.attrib.get('noautovalidity') is not None else False,
-                                                    len=self.getLen(param),
-                                                    extstructs=None,
-                                                    condition=None,
-                                                    cdecl=cdecl))
-            self.commands.append(self.CommandData(name=name, params=paramsInfo, cdecl=self.makeCDecls(cmdinfo.elem)[0]))
-    #
-    # Check if the parameter passed in is a pointer
-    def paramIsPointer(self, param):
-        ispointer = 0
-        paramtype = param.find('type')
-        if (paramtype.tail is not None) and ('*' in paramtype.tail):
-            ispointer = paramtype.tail.count('*')
-        elif paramtype.text[:4] == 'PFN_':
-            # Treat function pointer typedefs as a pointer to a single value
-            ispointer = 1
-        return ispointer
-    #
-    # Check if the parameter passed in is a static array
-    def paramIsStaticArray(self, param):
-        isstaticarray = 0
-        paramname = param.find('name')
-        if (paramname.tail is not None) and ('[' in paramname.tail):
-            isstaticarray = paramname.tail.count('[')
-        return isstaticarray
-    #
-    # Check if the parameter passed in is optional
-    # Returns a list of Boolean values for comma separated len attributes (len='false,true')
-    def paramIsOptional(self, param):
-        # See if the handle is optional
-        isoptional = False
-        # Simple, if it's optional, return true
-        optString = param.attrib.get('optional')
-        if optString:
-            if optString == 'true':
-                isoptional = True
-            elif ',' in optString:
-                opts = []
-                for opt in optString.split(','):
-                    val = opt.strip()
-                    if val == 'true':
-                        opts.append(True)
-                    elif val == 'false':
-                        opts.append(False)
-                    else:
-                        print('Unrecognized len attribute value',val)
-                isoptional = opts
-        return isoptional
-    #
-    # Check if the handle passed in is optional
-    # Uses the same logic as ValidityOutputGenerator.isHandleOptional
-    def isHandleOptional(self, param, lenParam):
-        # Simple, if it's optional, return true
-        if param.isoptional:
-            return True
-        # If no validity is being generated, it usually means that validity is complex and not absolute, so let's say yes.
-        if param.noautovalidity:
-            return True
-        # If the parameter is an array and we haven't already returned, find out if any of the len parameters are optional
-        if lenParam and lenParam.isoptional:
-            return True
-        return False
-    #
-    # Generate a VkStructureType based on a structure typename
-    def genVkStructureType(self, typename):
-        # Add underscore between lowercase then uppercase
-        value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', typename)
-        # Change to uppercase
-        value = value.upper()
-        # Add STRUCTURE_TYPE_
-        return re.sub('VK_', 'VK_STRUCTURE_TYPE_', value)
-    #
-    # Get the cached VkStructureType value for the specified struct typename, or generate a VkStructureType
-    # value assuming the struct is defined by a different feature
-    def getStructType(self, typename):
-        value = None
-        if typename in self.structTypes:
-            value = self.structTypes[typename].value
-        else:
-            value = self.genVkStructureType(typename)
-            self.logMsg('diag', 'ParameterValidation: Generating {} for {} structure type that was not defined by the current feature'.format(value, typename))
-        return value
-    #
-    # Retrieve the value of the len tag
-    def getLen(self, param):
-        result = None
-        len = param.attrib.get('len')
-        if len and len != 'null-terminated':
-            # For string arrays, 'len' can look like 'count,null-terminated',
-            # indicating that we have a null terminated array of strings.  We
-            # strip the null-terminated from the 'len' field and only return
-            # the parameter specifying the string count
-            if 'null-terminated' in len:
-                result = len.split(',')[0]
-            else:
-                result = len
-        return result
-    #
-    # Retrieve the type and name for a parameter
-    def getTypeNameTuple(self, param):
-        type = ''
-        name = ''
-        for elem in param:
-            if elem.tag == 'type':
-                type = noneStr(elem.text)
-            elif elem.tag == 'name':
-                name = noneStr(elem.text)
-        return (type, name)
-    #
-    # Find a named parameter in a parameter list
-    def getParamByName(self, params, name):
-        for param in params:
-            if param.name == name:
-                return param
-        return None
-    #
-    # Extract length values from latexmath.  Currently an inflexible solution that looks for specific
-    # patterns that are found in vk.xml.  Will need to be updated when new patterns are introduced.
-    def parseLateXMath(self, source):
-        name = 'ERROR'
-        decoratedName = 'ERROR'
-        if 'mathit' in source:
-            # Matches expressions similar to 'latexmath:[$\lceil{\mathit{rasterizationSamples} \over 32}\rceil$]'
-            match = re.match(r'latexmath\s*\:\s*\[\s*\$\\l(\w+)\s*\{\s*\\mathit\s*\{\s*(\w+)\s*\}\s*\\over\s*(\d+)\s*\}\s*\\r(\w+)\$\s*\]', source)
-            if not match or match.group(1) != match.group(4):
-                raise 'Unrecognized latexmath expression'
-            name = match.group(2)
-            decoratedName = '{}({}/{})'.format(*match.group(1, 2, 3))
-        else:
-            # Matches expressions similar to 'latexmath : [$dataSize \over 4$]'
-            match = re.match(r'latexmath\s*\:\s*\[\s*\$\s*(\w+)\s*\\over\s*(\d+)\s*\$\s*\]', source)
-            name = match.group(1)
-            decoratedName = '{}/{}'.format(*match.group(1, 2))
-        return name, decoratedName
-    #
-    # Get the length paramater record for the specified parameter name
-    def getLenParam(self, params, name):
-        lenParam = None
-        if name:
-            if '->' in name:
-                # The count is obtained by dereferencing a member of a struct parameter
-                lenParam = self.CommandParam(name=name, iscount=True, ispointer=False, isbool=False, israngedenum=False, isconst=False,
-                                             isstaticarray=None, isoptional=False, type=None, noautovalidity=False, len=None, extstructs=None,
-                                             condition=None, cdecl=None)
-            elif 'latexmath' in name:
-                lenName, decoratedName = self.parseLateXMath(name)
-                lenParam = self.getParamByName(params, lenName)
-                # TODO: Zero-check the result produced by the equation?
-                # Copy the stored len parameter entry and overwrite the name with the processed latexmath equation
-                #param = self.getParamByName(params, lenName)
-                #lenParam = self.CommandParam(name=decoratedName, iscount=param.iscount, ispointer=param.ispointer,
-                #                             isoptional=param.isoptional, type=param.type, len=param.len,
-                #                             isstaticarray=param.isstaticarray, extstructs=param.extstructs,
-                #                             noautovalidity=True, condition=None, cdecl=param.cdecl)
-            else:
-                lenParam = self.getParamByName(params, name)
-        return lenParam
-    #
-    # Convert a vulkan.h command declaration into a parameter_validation.h definition
-    def getCmdDef(self, cmd):
-        #
-        # Strip the trailing ';' and split into individual lines
-        lines = cmd.cdecl[:-1].split('\n')
-        # Replace Vulkan prototype
-        lines[0] = 'static bool parameter_validation_' + cmd.name + '('
-        # Replace the first argument with debug_report_data, when the first
-        # argument is a handle (not vkCreateInstance)
-        reportData = '    debug_report_data*'.ljust(self.genOpts.alignFuncParam) + 'report_data,'
-        if cmd.name != 'vkCreateInstance':
-            lines[1] = reportData
-        else:
-            lines.insert(1, reportData)
-        return '\n'.join(lines)
-    #
-    # Generate the code to check for a NULL dereference before calling the
-    # validation function
-    def genCheckedLengthCall(self, name, exprs):
-        count = name.count('->')
-        if count:
-            checkedExpr = []
-            localIndent = ''
-            elements = name.split('->')
-            # Open the if expression blocks
-            for i in range(0, count):
-                checkedExpr.append(localIndent + 'if ({} != NULL) {{\n'.format('->'.join(elements[0:i+1])))
-                localIndent = self.incIndent(localIndent)
-            # Add the validation expression
-            for expr in exprs:
-                checkedExpr.append(localIndent + expr)
-            # Close the if blocks
-            for i in range(0, count):
-                localIndent = self.decIndent(localIndent)
-                checkedExpr.append(localIndent + '}\n')
-            return [checkedExpr]
-        # No if statements were required
-        return exprs
-    #
-    # Generate code to check for a specific condition before executing validation code
-    def genConditionalCall(self, prefix, condition, exprs):
-        checkedExpr = []
-        localIndent = ''
-        formattedCondition = condition.format(prefix)
-        checkedExpr.append(localIndent + 'if ({})\n'.format(formattedCondition))
-        checkedExpr.append(localIndent + '{\n')
-        localIndent = self.incIndent(localIndent)
-        for expr in exprs:
-            checkedExpr.append(localIndent + expr)
-        localIndent = self.decIndent(localIndent)
-        checkedExpr.append(localIndent + '}\n')
-        return [checkedExpr]
-    #
-    # Generate the sType check string
-    def makeStructTypeCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, lenPtrRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
-        checkExpr = []
-        stype = self.structTypes[value.type]
-        if lenValue:
-            # This is an array with a pointer to a count value
-            if lenValue.ispointer:
-                # When the length parameter is a pointer, there is an extra Boolean parameter in the function call to indicate if it is required
-                checkExpr.append('skipCall |= validate_struct_type_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, "{sv}", {pf}{ln}, {pf}{vn}, {sv}, {}, {}, {});\n'.format(
-                    funcPrintName, lenPtrRequired, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, sv=stype.value, pf=prefix, **postProcSpec))
-            # This is an array with an integer count value
-            else:
-                checkExpr.append('skipCall |= validate_struct_type_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, "{sv}", {pf}{ln}, {pf}{vn}, {sv}, {}, {});\n'.format(
-                    funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, sv=stype.value, pf=prefix, **postProcSpec))
-        # This is an individual struct
-        else:
-            checkExpr.append('skipCall |= validate_struct_type(report_data, "{}", {ppp}"{}"{pps}, "{sv}", {}{vn}, {sv}, {});\n'.format(
-                funcPrintName, valuePrintName, prefix, valueRequired, vn=value.name, sv=stype.value, **postProcSpec))
-        return checkExpr
-    #
-    # Generate the handle check string
-    def makeHandleCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
-        checkExpr = []
-        if lenValue:
-            if lenValue.ispointer:
-                # This is assumed to be an output array with a pointer to a count value
-                raise('Unsupported parameter validation case: Output handle array elements are not NULL checked')
-            else:
-                # This is an array with an integer count value
-                checkExpr.append('skipCall |= validate_handle_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(
-                    funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
-        else:
-            # This is assumed to be an output handle pointer
-            raise('Unsupported parameter validation case: Output handles are not NULL checked')
-        return checkExpr
-    #
-    # Generate check string for an array of VkFlags values
-    def makeFlagsArrayCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
-        checkExpr = []
-        flagBitsName = value.type.replace('Flags', 'FlagBits')
-        if not flagBitsName in self.flagBits:
-            raise('Unsupported parameter validation case: array of reserved VkFlags')
-        else:
-            allFlags = 'All' + flagBitsName
-            checkExpr.append('skipCall |= validate_flags_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, "{}", {}, {pf}{}, {pf}{}, {}, {});\n'.format(funcPrintName, lenPrintName, valuePrintName, flagBitsName, allFlags, lenValue.name, value.name, lenValueRequired, valueRequired, pf=prefix, **postProcSpec))
-        return checkExpr
-    #
-    # Generate pNext check string
-    def makeStructNextCheck(self, prefix, value, funcPrintName, valuePrintName, postProcSpec):
-        checkExpr = []
-        # Generate an array of acceptable VkStructureType values for pNext
-        extStructCount = 0
-        extStructVar = 'NULL'
-        extStructNames = 'NULL'
-        if value.extstructs:
-            structs = value.extstructs.split(',')
-            checkExpr.append('const VkStructureType allowedStructs[] = {' + ', '.join([self.getStructType(s) for s in structs]) + '};\n')
-            extStructCount = 'ARRAY_SIZE(allowedStructs)'
-            extStructVar = 'allowedStructs'
-            extStructNames = '"' + ', '.join(structs) + '"'
-        checkExpr.append('skipCall |= validate_struct_pnext(report_data, "{}", {ppp}"{}"{pps}, {}, {}{}, {}, {}, GeneratedHeaderVersion);\n'.format(
-            funcPrintName, valuePrintName, extStructNames, prefix, value.name, extStructCount, extStructVar, **postProcSpec))
-        return checkExpr
-    #
-    # Generate the pointer check string
-    def makePointerCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, lenPtrRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
-        checkExpr = []
-        if lenValue:
-            # This is an array with a pointer to a count value
-            if lenValue.ispointer:
-                # If count and array parameters are optional, there will be no validation
-                if valueRequired == 'true' or lenPtrRequired == 'true' or lenValueRequired == 'true':
-                    # When the length parameter is a pointer, there is an extra Boolean parameter in the function call to indicate if it is required
-                    checkExpr.append('skipCall |= validate_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {}, {});\n'.format(
-                        funcPrintName, lenPtrRequired, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
-            # This is an array with an integer count value
-            else:
-                # If count and array parameters are optional, there will be no validation
-                if valueRequired == 'true' or lenValueRequired == 'true':
-                    # Arrays of strings receive special processing
-                    validationFuncName = 'validate_array' if value.type != 'char' else 'validate_string_array'
-                    checkExpr.append('skipCall |= {}(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(
-                        validationFuncName, funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
-            if checkExpr:
-                if lenValue and ('->' in lenValue.name):
-                    # Add checks to ensure the validation call does not dereference a NULL pointer to obtain the count
-                    checkExpr = self.genCheckedLengthCall(lenValue.name, checkExpr)
-        # This is an individual struct that is not allowed to be NULL
-        elif not value.isoptional:
-            # Function pointers need a reinterpret_cast to void*
-            if value.type[:4] == 'PFN_':
-                checkExpr.append('skipCall |= validate_required_pointer(report_data, "{}", {ppp}"{}"{pps}, reinterpret_cast<const void*>({}{}));\n'.format(funcPrintName, valuePrintName, prefix, value.name, **postProcSpec))
-            else:
-                checkExpr.append('skipCall |= validate_required_pointer(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcPrintName, valuePrintName, prefix, value.name, **postProcSpec))
-        return checkExpr
-    #
-    # Process struct member validation code, performing name suibstitution if required
-    def processStructMemberCode(self, line, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec):
-        # Build format specifier list
-        kwargs = {}
-        if '{postProcPrefix}' in line:
-            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
-            if type(memberDisplayNamePrefix) is tuple:
-                kwargs['postProcPrefix'] = 'ParameterName('
-            else:
-                kwargs['postProcPrefix'] = postProcSpec['ppp']
-        if '{postProcSuffix}' in line:
-            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
-            if type(memberDisplayNamePrefix) is tuple:
-                kwargs['postProcSuffix'] = ', ParameterName::IndexVector{{ {}{} }})'.format(postProcSpec['ppi'], memberDisplayNamePrefix[1])
-            else:
-                kwargs['postProcSuffix'] = postProcSpec['pps']
-        if '{postProcInsert}' in line:
-            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
-            if type(memberDisplayNamePrefix) is tuple:
-                kwargs['postProcInsert'] = '{}{}, '.format(postProcSpec['ppi'], memberDisplayNamePrefix[1])
-            else:
-                kwargs['postProcInsert'] = postProcSpec['ppi']
-        if '{funcName}' in line:
-            kwargs['funcName'] = funcName
-        if '{valuePrefix}' in line:
-            kwargs['valuePrefix'] = memberNamePrefix
-        if '{displayNamePrefix}' in line:
-            # Check for a tuple that includes a format string and format parameters to be used with the ParameterName class
-            if type(memberDisplayNamePrefix) is tuple:
-                kwargs['displayNamePrefix'] = memberDisplayNamePrefix[0]
-            else:
-                kwargs['displayNamePrefix'] = memberDisplayNamePrefix
-
-        if kwargs:
-            # Need to escape the C++ curly braces
-            if 'IndexVector' in line:
-                line = line.replace('IndexVector{ ', 'IndexVector{{ ')
-                line = line.replace(' }),', ' }}),')
-            return line.format(**kwargs)
-        return line
-    #
-    # Process struct validation code for inclusion in function or parent struct validation code
-    def expandStructCode(self, lines, funcName, memberNamePrefix, memberDisplayNamePrefix, indent, output, postProcSpec):
-        for line in lines:
-            if output:
-                output[-1] += '\n'
-            if type(line) is list:
-                for sub in line:
-                    output.append(self.processStructMemberCode(indent + sub, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec))
-            else:
-                output.append(self.processStructMemberCode(indent + line, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec))
-        return output
-    #
-    # Process struct pointer/array validation code, perfoeming name substitution if required
-    def expandStructPointerCode(self, prefix, value, lenValue, funcName, valueDisplayName, postProcSpec):
-        expr = []
-        expr.append('if ({}{} != NULL)\n'.format(prefix, value.name))
-        expr.append('{')
-        indent = self.incIndent(None)
-        if lenValue:
-            # Need to process all elements in the array
-            indexName = lenValue.name.replace('Count', 'Index')
-            expr[-1] += '\n'
-            expr.append(indent + 'for (uint32_t {iname} = 0; {iname} < {}{}; ++{iname})\n'.format(prefix, lenValue.name, iname=indexName))
-            expr.append(indent + '{')
-            indent = self.incIndent(indent)
-            # Prefix for value name to display in error message
-            memberNamePrefix = '{}{}[{}].'.format(prefix, value.name, indexName)
-            memberDisplayNamePrefix = ('{}[%i].'.format(valueDisplayName), indexName)
-        else:
-            memberNamePrefix = '{}{}->'.format(prefix, value.name)
-            memberDisplayNamePrefix = '{}->'.format(valueDisplayName)
-        #
-        # Expand the struct validation lines
-        expr = self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, indent, expr, postProcSpec)
-        #
-        if lenValue:
-            # Close if and for scopes
-            indent = self.decIndent(indent)
-            expr.append(indent + '}\n')
-        expr.append('}\n')
-        return expr
-    #
-    # Generate the parameter checking code
-    def genFuncBody(self, funcName, values, valuePrefix, displayNamePrefix, structTypeName):
-        lines = []    # Generated lines of code
-        unused = []   # Unused variable names
-        for value in values:
-            usedLines = []
-            lenParam = None
-            #
-            # Prefix and suffix for post processing of parameter names for struct members.  Arrays of structures need special processing to include the array index in the full parameter name.
-            postProcSpec = {}
-            postProcSpec['ppp'] = '' if not structTypeName else '{postProcPrefix}'
-            postProcSpec['pps'] = '' if not structTypeName else '{postProcSuffix}'
-            postProcSpec['ppi'] = '' if not structTypeName else '{postProcInsert}'
-            #
-            # Generate the full name of the value, which will be printed in the error message, by adding the variable prefix to the value name
-            valueDisplayName = '{}{}'.format(displayNamePrefix, value.name)
-            #
-            # Check for NULL pointers, ignore the inout count parameters that
-            # will be validated with their associated array
-            if (value.ispointer or value.isstaticarray) and not value.iscount:
-                #
-                # Parameters for function argument generation
-                req = 'true'    # Paramerter cannot be NULL
-                cpReq = 'true'  # Count pointer cannot be NULL
-                cvReq = 'true'  # Count value cannot be 0
-                lenDisplayName = None # Name of length parameter to print with validation messages; parameter name with prefix applied
-                #
-                # Generate required/optional parameter strings for the pointer and count values
-                if value.isoptional:
-                    req = 'false'
-                if value.len:
-                    # The parameter is an array with an explicit count parameter
-                    lenParam = self.getLenParam(values, value.len)
-                    lenDisplayName = '{}{}'.format(displayNamePrefix, lenParam.name)
-                    if lenParam.ispointer:
-                        # Count parameters that are pointers are inout
-                        if type(lenParam.isoptional) is list:
-                            if lenParam.isoptional[0]:
-                                cpReq = 'false'
-                            if lenParam.isoptional[1]:
-                                cvReq = 'false'
-                        else:
-                            if lenParam.isoptional:
-                                cpReq = 'false'
-                    else:
-                        if lenParam.isoptional:
-                            cvReq = 'false'
-                #
-                # The parameter will not be processes when tagged as 'noautovalidity'
-                # For the pointer to struct case, the struct pointer will not be validated, but any
-                # members not tagged as 'noatuvalidity' will be validated
-                if value.noautovalidity:
-                    # Log a diagnostic message when validation cannot be automatically generated and must be implemented manually
-                    self.logMsg('diag', 'ParameterValidation: No validation for {} {}'.format(structTypeName if structTypeName else funcName, value.name))
-                else:
-                    #
-                    # If this is a pointer to a struct with an sType field, verify the type
-                    if value.type in self.structTypes:
-                        usedLines += self.makeStructTypeCheck(valuePrefix, value, lenParam, req, cvReq, cpReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
-                    # If this is an input handle array that is not allowed to contain NULL handles, verify that none of the handles are VK_NULL_HANDLE
-                    elif value.type in self.handleTypes and value.isconst and not self.isHandleOptional(value, lenParam):
-                        usedLines += self.makeHandleCheck(valuePrefix, value, lenParam, req, cvReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
-                    elif value.type in self.flags and value.isconst:
-                        usedLines += self.makeFlagsArrayCheck(valuePrefix, value, lenParam, req, cvReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
-                    elif value.isbool and value.isconst:
-                        usedLines.append('skipCall |= validate_bool32_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, {pf}{}, {pf}{}, {}, {});\n'.format(funcName, lenDisplayName, valueDisplayName, lenParam.name, value.name, cvReq, req, pf=valuePrefix, **postProcSpec))
-                    elif value.israngedenum and value.isconst:
-                        enumRange = self.enumRanges[value.type]
-                        usedLines.append('skipCall |= validate_ranged_enum_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, "{}", {}, {}, {pf}{}, {pf}{}, {}, {});\n'.format(funcName, lenDisplayName, valueDisplayName, value.type, enumRange[0], enumRange[1], lenParam.name, value.name, cvReq, req, pf=valuePrefix, **postProcSpec))
-                    elif value.name == 'pNext':
-                        # We need to ignore VkDeviceCreateInfo and VkInstanceCreateInfo, as the loader manipulates them in a way that is not documented in vk.xml
-                        if not structTypeName in ['VkDeviceCreateInfo', 'VkInstanceCreateInfo']:
-                            usedLines += self.makeStructNextCheck(valuePrefix, value, funcName, valueDisplayName, postProcSpec)
-                    else:
-                        usedLines += self.makePointerCheck(valuePrefix, value, lenParam, req, cvReq, cpReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
-                    #
-                    # If this is a pointer to a struct (input), see if it contains members that need to be checked
-                    if value.type in self.validatedStructs and value.isconst:
-                        usedLines.append(self.expandStructPointerCode(valuePrefix, value, lenParam, funcName, valueDisplayName, postProcSpec))
-            # Non-pointer types
-            else:
-                #
-                # The parameter will not be processes when tagged as 'noautovalidity'
-                # For the struct case, the struct type will not be validated, but any
-                # members not tagged as 'noatuvalidity' will be validated
-                if value.noautovalidity:
-                    # Log a diagnostic message when validation cannot be automatically generated and must be implemented manually
-                    self.logMsg('diag', 'ParameterValidation: No validation for {} {}'.format(structTypeName if structTypeName else funcName, value.name))
-                else:
-                    if value.type in self.structTypes:
-                        stype = self.structTypes[value.type]
-                        usedLines.append('skipCall |= validate_struct_type(report_data, "{}", {ppp}"{}"{pps}, "{sv}", &({}{vn}), {sv}, false);\n'.format(
-                            funcName, valueDisplayName, valuePrefix, vn=value.name, sv=stype.value, **postProcSpec))
-                    elif value.type in self.handleTypes:
-                        if not self.isHandleOptional(value, None):
-                            usedLines.append('skipCall |= validate_required_handle(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcName, valueDisplayName, valuePrefix, value.name, **postProcSpec))
-                    elif value.type in self.flags:
-                        flagBitsName = value.type.replace('Flags', 'FlagBits')
-                        if not flagBitsName in self.flagBits:
-                            usedLines.append('skipCall |= validate_reserved_flags(report_data, "{}", {ppp}"{}"{pps}, {pf}{});\n'.format(funcName, valueDisplayName, value.name, pf=valuePrefix, **postProcSpec))
-                        else:
-                            flagsRequired = 'false' if value.isoptional else 'true'
-                            allFlagsName = 'All' + flagBitsName
-                            usedLines.append('skipCall |= validate_flags(report_data, "{}", {ppp}"{}"{pps}, "{}", {}, {pf}{}, {});\n'.format(funcName, valueDisplayName, flagBitsName, allFlagsName, value.name, flagsRequired, pf=valuePrefix, **postProcSpec))
-                    elif value.isbool:
-                        usedLines.append('skipCall |= validate_bool32(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcName, valueDisplayName, valuePrefix, value.name, **postProcSpec))
-                    elif value.israngedenum:
-                        enumRange = self.enumRanges[value.type]
-                        usedLines.append('skipCall |= validate_ranged_enum(report_data, "{}", {ppp}"{}"{pps}, "{}", {}, {}, {}{});\n'.format(funcName, valueDisplayName, value.type, enumRange[0], enumRange[1], valuePrefix, value.name, **postProcSpec))
-                    #
-                    # If this is a struct, see if it contains members that need to be checked
-                    if value.type in self.validatedStructs:
-                        memberNamePrefix = '{}{}.'.format(valuePrefix, value.name)
-                        memberDisplayNamePrefix = '{}.'.format(valueDisplayName)
-                        usedLines.append(self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, '', [], postProcSpec))
-            #
-            # Append the parameter check to the function body for the current command
-            if usedLines:
-                # Apply special conditional checks
-                if value.condition:
-                    usedLines = self.genConditionalCall(valuePrefix, value.condition, usedLines)
-                lines += usedLines
-            elif not value.iscount:
-                # If no expression was generated for this value, it is unreferenced by the validation function, unless
-                # it is an array count, which is indirectly referenced for array valiadation.
-                unused.append(value.name)
-        return lines, unused
-    #
-    # Generate the struct member check code from the captured data
-    def processStructMemberData(self):
-        indent = self.incIndent(None)
-        for struct in self.structMembers:
-            #
-            # The string returned by genFuncBody will be nested in an if check for a NULL pointer, so needs its indent incremented
-            lines, unused = self.genFuncBody('{funcName}', struct.members, '{valuePrefix}', '{displayNamePrefix}', struct.name)
-            if lines:
-                self.validatedStructs[struct.name] = lines
-    #
-    # Generate the command param check code from the captured data
-    def processCmdData(self):
-        indent = self.incIndent(None)
-        for command in self.commands:
-            # Skip first parameter if it is a dispatch handle (everything except vkCreateInstance)
-            startIndex = 0 if command.name == 'vkCreateInstance' else 1
-            lines, unused = self.genFuncBody(command.name, command.params[startIndex:], '', '', None)
-            if lines:
-                cmdDef = self.getCmdDef(command) + '\n'
-                cmdDef += '{\n'
-                # Process unused parameters, Ignoring the first dispatch handle parameter, which is not
-                # processed by parameter_validation (except for vkCreateInstance, which does not have a
-                # handle as its first parameter)
-                if unused:
-                    for name in unused:
-                        cmdDef += indent + 'UNUSED_PARAMETER({});\n'.format(name)
-                    if len(unused) > 0:
-                        cmdDef += '\n'
-                cmdDef += indent + 'bool skipCall = false;\n'
-                for line in lines:
-                    cmdDef += '\n'
-                    if type(line) is list:
-                        for sub in line:
-                            cmdDef += indent + sub
-                    else:
-                        cmdDef += indent + line
-                cmdDef += '\n'
-                cmdDef += indent + 'return skipCall;\n'
-                cmdDef += '}\n'
-                self.appendSection('command', cmdDef)
diff --git a/genvk.py b/genvk.py
deleted file mode 100755
index 993477c..0000000
--- a/genvk.py
+++ /dev/null
@@ -1,358 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013-2016 The Khronos Group 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.
-
-import sys, time, pdb, string, cProfile
-from reg import *
-from generator import write, CGeneratorOptions, COutputGenerator, DocGeneratorOptions, DocOutputGenerator, PyOutputGenerator, ValidityOutputGenerator, HostSynchronizationOutputGenerator, ThreadGeneratorOptions, ThreadOutputGenerator
-from generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
-
-# debug - start header generation in debugger
-# dump - dump registry after loading
-# profile - enable Python profiling
-# protect - whether to use #ifndef protections
-# registry <filename> - use specified XML registry instead of gl.xml
-# target - string name of target header, or all targets if None
-# timeit - time length of registry loading & header generation
-# validate - validate return & parameter group tags against <group>
-debug   = False
-dump    = False
-profile = False
-protect = True
-target  = None
-timeit  = False
-validate= False
-# Default input / log files
-errFilename = None
-diagFilename = 'diag.txt'
-regFilename = 'vk.xml'
-outDir = '.'
-
-if __name__ == '__main__':
-    i = 1
-    while (i < len(sys.argv)):
-        arg = sys.argv[i]
-        i = i + 1
-        if (arg == '-debug'):
-            write('Enabling debug (-debug)', file=sys.stderr)
-            debug = True
-        elif (arg == '-dump'):
-            write('Enabling dump (-dump)', file=sys.stderr)
-            dump = True
-        elif (arg == '-noprotect'):
-            write('Disabling inclusion protection in output headers', file=sys.stderr)
-            protect = False
-        elif (arg == '-profile'):
-            write('Enabling profiling (-profile)', file=sys.stderr)
-            profile = True
-        elif (arg == '-registry'):
-            regFilename = sys.argv[i]
-            i = i+1
-            write('Using registry ', regFilename, file=sys.stderr)
-        elif (arg == '-time'):
-            write('Enabling timing (-time)', file=sys.stderr)
-            timeit = True
-        elif (arg == '-validate'):
-            write('Enabling group validation (-validate)', file=sys.stderr)
-            validate = True
-        elif (arg == '-outdir'):
-            outDir = sys.argv[i]
-            i = i+1
-            write('Using output directory ', outDir, file=sys.stderr)
-        elif (arg[0:1] == '-'):
-            write('Unrecognized argument:', arg, file=sys.stderr)
-            exit(1)
-        else:
-            target = arg
-            write('Using target', target, file=sys.stderr)
-
-# Simple timer functions
-startTime = None
-def startTimer():
-    global startTime
-    startTime = time.clock()
-def endTimer(msg):
-    global startTime
-    endTime = time.clock()
-    if (timeit):
-        write(msg, endTime - startTime)
-        startTime = None
-
-# Load & parse registry
-reg = Registry()
-
-startTimer()
-tree = etree.parse(regFilename)
-endTimer('Time to make ElementTree =')
-
-startTimer()
-reg.loadElementTree(tree)
-endTimer('Time to parse ElementTree =')
-
-if (validate):
-    reg.validateGroups()
-
-if (dump):
-    write('***************************************')
-    write('Performing Registry dump to regdump.txt')
-    write('***************************************')
-    reg.dumpReg(filehandle = open('regdump.txt','w'))
-
-# Turn a list of strings into a regexp string matching exactly those strings
-def makeREstring(list):
-    return '^(' + '|'.join(list) + ')$'
-
-# Descriptive names for various regexp patterns used to select
-# versions and extensions
-allVersions     = allExtensions = '.*'
-noVersions      = noExtensions = None
-
-# Copyright text prefixing all headers (list of strings).
-prefixStrings = [
-    '/*',
-    '** Copyright (c) 2015-2016 The Khronos Group 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.',
-    '*/',
-    ''
-]
-
-# Text specific to Vulkan headers
-vkPrefixStrings = [
-    '/*',
-    '** This header is generated from the Khronos Vulkan XML API Registry.',
-    '**',
-    '*/',
-    ''
-]
-
-# Defaults for generating re-inclusion protection wrappers (or not)
-protectFile = protect
-protectFeature = protect
-protectProto = protect
-
-buildList = [
-    # Vulkan 1.0 - header for core API + extensions.
-    # To generate just the core API,
-    # change to 'defaultExtensions = None' below.
-    [ COutputGenerator,
-      CGeneratorOptions(
-        filename          = 'include/vulkan/vulkan.h',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = 'vulkan',
-        addExtensions     = None,
-        removeExtensions  = None,
-        prefixText        = prefixStrings + vkPrefixStrings,
-        genFuncPointers   = True,
-        protectFile       = protectFile,
-        protectFeature    = False,
-        protectProto      = '#ifndef',
-        protectProtoStr   = 'VK_NO_PROTOTYPES',
-        apicall           = 'VKAPI_ATTR ',
-        apientry          = 'VKAPI_CALL ',
-        apientryp         = 'VKAPI_PTR *',
-        alignFuncParam    = 48)
-    ],
-    # Vulkan 1.0 draft - API include files for spec and ref pages
-    # Overwrites include subdirectories in spec source tree
-    # The generated include files do not include the calling convention
-    # macros (apientry etc.), unlike the header files.
-    # Because the 1.0 core branch includes ref pages for extensions,
-    # all the extension interfaces need to be generated, even though
-    # none are used by the core spec itself.
-    [ DocOutputGenerator,
-      DocGeneratorOptions(
-        filename          = 'vulkan-docs',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = None,
-        addExtensions     =
-            makeREstring([
-                'VK_KHR_sampler_mirror_clamp_to_edge',
-            ]),
-        removeExtensions  =
-            makeREstring([
-            ]),
-        prefixText        = prefixStrings + vkPrefixStrings,
-        apicall           = '',
-        apientry          = '',
-        apientryp         = '*',
-        genDirectory      = '../../doc/specs/vulkan',
-        alignFuncParam    = 48,
-        expandEnumerants  = False)
-    ],
-    # Vulkan 1.0 draft - API names to validate man/api spec includes & links
-    [ PyOutputGenerator,
-      DocGeneratorOptions(
-        filename          = '../../doc/specs/vulkan/vkapi.py',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = None,
-        addExtensions     =
-            makeREstring([
-                'VK_KHR_sampler_mirror_clamp_to_edge',
-            ]),
-        removeExtensions  =
-            makeREstring([
-            ]))
-    ],
-    # Vulkan 1.0 draft - core API validity files for spec
-    # Overwrites validity subdirectories in spec source tree
-    [ ValidityOutputGenerator,
-      DocGeneratorOptions(
-        filename          = 'validity',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = None,
-        addExtensions     =
-            makeREstring([
-                'VK_KHR_sampler_mirror_clamp_to_edge',
-            ]),
-        removeExtensions  =
-            makeREstring([
-            ]),
-        genDirectory      = '../../doc/specs/vulkan')
-    ],
-    # Vulkan 1.0 draft - core API host sync table files for spec
-    # Overwrites subdirectory in spec source tree
-    [ HostSynchronizationOutputGenerator,
-      DocGeneratorOptions(
-        filename          = 'hostsynctable',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = None,
-        addExtensions     =
-            makeREstring([
-                'VK_KHR_sampler_mirror_clamp_to_edge',
-            ]),
-        removeExtensions  =
-            makeREstring([
-            ]),
-        genDirectory      = '../../doc/specs/vulkan')
-    ],
-    # Vulkan 1.0 draft - thread checking layer
-    [ ThreadOutputGenerator,
-      ThreadGeneratorOptions(
-        filename          = 'thread_check.h',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = 'vulkan',
-        addExtensions     = None,
-        removeExtensions  = None,
-        prefixText        = prefixStrings + vkPrefixStrings,
-        genFuncPointers   = True,
-        protectFile       = protectFile,
-        protectFeature    = False,
-        protectProto      = True,
-        protectProtoStr   = 'VK_PROTOTYPES',
-        apicall           = 'VKAPI_ATTR ',
-        apientry          = 'VKAPI_CALL ',
-        apientryp         = 'VKAPI_PTR *',
-        alignFuncParam    = 48,
-        genDirectory      = outDir)
-    ],
-    [ ParamCheckerOutputGenerator,
-      ParamCheckerGeneratorOptions(
-        filename          = 'parameter_validation.h',
-        apiname           = 'vulkan',
-        profile           = None,
-        versions          = allVersions,
-        emitversions      = allVersions,
-        defaultExtensions = 'vulkan',
-        addExtensions     = None,
-        removeExtensions  = None,
-        prefixText        = prefixStrings + vkPrefixStrings,
-        genFuncPointers   = True,
-        protectFile       = protectFile,
-        protectFeature    = False,
-        protectProto      = None,
-        protectProtoStr   = 'VK_NO_PROTOTYPES',
-        apicall           = 'VKAPI_ATTR ',
-        apientry          = 'VKAPI_CALL ',
-        apientryp         = 'VKAPI_PTR *',
-        alignFuncParam    = 48,
-        genDirectory      = outDir)
-    ],
-    None
-]
-
-# create error/warning & diagnostic files
-if (errFilename):
-    errWarn = open(errFilename,'w')
-else:
-    errWarn = sys.stderr
-diag = open(diagFilename, 'w')
-
-# check that output directory exists
-if (not os.path.isdir(outDir)):
-    write('Output directory does not exist: ', outDir)
-    raise
-
-def genHeaders():
-    # Loop over targets, building each
-    generated = 0
-    for item in buildList:
-        if (item == None):
-            break
-        createGenerator = item[0]
-        genOpts = item[1]
-        if (target and target != genOpts.filename):
-            # write('*** Skipping', genOpts.filename)
-            continue
-        write('*** Building', genOpts.filename)
-        generated = generated + 1
-        startTimer()
-        gen = createGenerator(errFile=errWarn,
-                              warnFile=errWarn,
-                              diagFile=diag)
-        reg.setGenerator(gen)
-        reg.apiGen(genOpts)
-        write('** Generated', genOpts.filename)
-        endTimer('Time to generate ' + genOpts.filename + ' =')
-    if (target and generated == 0):
-        write('Failed to generate target:', target)
-
-if (debug):
-    pdb.run('genHeaders()')
-elif (profile):
-    import cProfile, pstats
-    cProfile.run('genHeaders()', 'profile.txt')
-    p = pstats.Stats('profile.txt')
-    p.strip_dirs().sort_stats('time').print_stats(50)
-else:
-    genHeaders()
diff --git a/glslang_revision b/glslang_revision
index 5c29602..75598cb 100644
--- a/glslang_revision
+++ b/glslang_revision
@@ -1 +1 @@
-81cd764b5ffc475bc73f1fb35f75fd1171bb2343
+3fc1543794d1c368d690e60eaac6111c8c436aa7
diff --git a/include/vulkan/vk_icd.h b/include/vulkan/vk_icd.h
index a649364..7b54fb5 100644
--- a/include/vulkan/vk_icd.h
+++ b/include/vulkan/vk_icd.h
@@ -28,7 +28,7 @@
 /*
  * Loader-ICD version negotiation API
  */
-#define CURRENT_LOADER_ICD_INTERFACE_VERSION 2
+#define CURRENT_LOADER_ICD_INTERFACE_VERSION 3
 #define MIN_SUPPORTED_LOADER_ICD_INTERFACE_VERSION 0
 typedef VkResult (VKAPI_PTR *PFN_vkNegotiateLoaderICDInterfaceVersion)(uint32_t *pVersion);
 /*
@@ -111,6 +111,12 @@
 } VkIcdSurfaceXlib;
 #endif // VK_USE_PLATFORM_XLIB_KHR
 
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+typedef struct {
+    ANativeWindow* window;
+} VkIcdSurfaceAndroid;
+#endif //VK_USE_PLATFORM_ANDROID_KHR
+
 typedef struct {
     VkIcdSurfaceBase base;
     VkDisplayModeKHR displayMode;
@@ -121,4 +127,5 @@
     VkDisplayPlaneAlphaFlagBitsKHR alphaMode;
     VkExtent2D imageExtent;
 } VkIcdSurfaceDisplay;
+
 #endif // VKICD_H
diff --git a/include/vulkan/vk_platform.h b/include/vulkan/vk_platform.h
index e51851a..0fa62ee 100644
--- a/include/vulkan/vk_platform.h
+++ b/include/vulkan/vk_platform.h
@@ -53,7 +53,7 @@
     #define VKAPI_PTR  VKAPI_CALL
 #elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
     #error "Vulkan isn't supported for the 'armeabi' NDK ABI"
-#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && __ARM_32BIT_STATE
+#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
     // On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
     // calling convention, i.e. float parameters are passed in registers. This
     // is true even if the rest of the application passes floats on the stack,
diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
index 50bbb02..0cad6bf 100644
--- a/include/vulkan/vulkan.h
+++ b/include/vulkan/vulkan.h
@@ -43,7 +43,7 @@
 #define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
 #define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
 // Version of this file
-#define VK_HEADER_VERSION 26
+#define VK_HEADER_VERSION 31
 
 
 #define VK_NULL_HANDLE 0
@@ -225,6 +225,7 @@
     VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
     VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
     VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
+    VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
     VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
     VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
     VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
@@ -3972,8 +3973,8 @@
 
 
 #define VK_AMD_draw_indirect_count 1
-#define VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
-#define VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
+#define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1
+#define VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME "VK_AMD_draw_indirect_count"
 
 typedef void (VKAPI_PTR *PFN_vkCmdDrawIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
 typedef void (VKAPI_PTR *PFN_vkCmdDrawIndexedIndirectCountAMD)(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount, uint32_t stride);
@@ -3998,6 +3999,21 @@
     uint32_t                                    stride);
 #endif
 
+#define VK_AMD_negative_viewport_height 1
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION 0
+#define VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME "VK_AMD_negative_viewport_height"
+
+
+#define VK_AMD_gpu_shader_half_float 1
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION 1
+#define VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME "VK_AMD_gpu_shader_half_float"
+
+
+#define VK_AMD_shader_ballot 1
+#define VK_AMD_SHADER_BALLOT_SPEC_VERSION 0
+#define VK_AMD_SHADER_BALLOT_EXTENSION_NAME "VK_AMD_shader_ballot"
+
+
 #define VK_IMG_format_pvrtc 1
 #define VK_IMG_FORMAT_PVRTC_SPEC_VERSION  1
 #define VK_IMG_FORMAT_PVRTC_EXTENSION_NAME "VK_IMG_format_pvrtc"
@@ -4116,6 +4132,28 @@
 
 #endif /* VK_USE_PLATFORM_WIN32_KHR */
 
+#define VK_EXT_validation_flags 1
+#define VK_EXT_VALIDATION_FLAGS_SPEC_VERSION 1
+#define VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME "VK_EXT_validation_flags"
+
+
+typedef enum VkValidationCheckEXT {
+    VK_VALIDATION_CHECK_ALL_EXT = 0,
+    VK_VALIDATION_CHECK_BEGIN_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT,
+    VK_VALIDATION_CHECK_END_RANGE_EXT = VK_VALIDATION_CHECK_ALL_EXT,
+    VK_VALIDATION_CHECK_RANGE_SIZE_EXT = (VK_VALIDATION_CHECK_ALL_EXT - VK_VALIDATION_CHECK_ALL_EXT + 1),
+    VK_VALIDATION_CHECK_MAX_ENUM_EXT = 0x7FFFFFFF
+} VkValidationCheckEXT;
+
+typedef struct VkValidationFlagsEXT {
+    VkStructureType          sType;
+    const void*              pNext;
+    uint32_t                 disabledValidationCheckCount;
+    VkValidationCheckEXT*    pDisabledValidationChecks;
+} VkValidationFlagsEXT;
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/vulkan/vulkan.hpp b/include/vulkan/vulkan.hpp
index ddcd876..b757029 100644
--- a/include/vulkan/vulkan.hpp
+++ b/include/vulkan/vulkan.hpp
@@ -40,7 +40,7 @@
 # include <vector>
 #endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
 
-static_assert( VK_HEADER_VERSION ==  26 , "Wrong VK_HEADER_VERSION!" );
+static_assert( VK_HEADER_VERSION ==  31 , "Wrong VK_HEADER_VERSION!" );
 
 // 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.
 // To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION
@@ -4114,35 +4114,6 @@
 
   struct DisplayPlanePropertiesKHR
   {
-    DisplayPlanePropertiesKHR( DisplayKHR currentDisplay_ = DisplayKHR(), uint32_t currentStackIndex_ = 0 )
-      : currentDisplay( currentDisplay_ )
-      , currentStackIndex( currentStackIndex_ )
-    {
-    }
-
-    DisplayPlanePropertiesKHR( VkDisplayPlanePropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPlanePropertiesKHR) );
-    }
-
-    DisplayPlanePropertiesKHR& operator=( VkDisplayPlanePropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPlanePropertiesKHR) );
-      return *this;
-    }
-
-    DisplayPlanePropertiesKHR& setCurrentDisplay( DisplayKHR currentDisplay_ )
-    {
-      currentDisplay = currentDisplay_;
-      return *this;
-    }
-
-    DisplayPlanePropertiesKHR& setCurrentStackIndex( uint32_t currentStackIndex_ )
-    {
-      currentStackIndex = currentStackIndex_;
-      return *this;
-    }
-
     operator const VkDisplayPlanePropertiesKHR&() const
     {
       return *reinterpret_cast<const VkDisplayPlanePropertiesKHR*>(this);
@@ -4218,35 +4189,6 @@
 
   struct DisplayModePropertiesKHR
   {
-    DisplayModePropertiesKHR( DisplayModeKHR displayMode_ = DisplayModeKHR(), DisplayModeParametersKHR parameters_ = DisplayModeParametersKHR() )
-      : displayMode( displayMode_ )
-      , parameters( parameters_ )
-    {
-    }
-
-    DisplayModePropertiesKHR( VkDisplayModePropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayModePropertiesKHR) );
-    }
-
-    DisplayModePropertiesKHR& operator=( VkDisplayModePropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayModePropertiesKHR) );
-      return *this;
-    }
-
-    DisplayModePropertiesKHR& setDisplayMode( DisplayModeKHR displayMode_ )
-    {
-      displayMode = displayMode_;
-      return *this;
-    }
-
-    DisplayModePropertiesKHR& setParameters( DisplayModeParametersKHR parameters_ )
-    {
-      parameters = parameters_;
-      return *this;
-    }
-
     operator const VkDisplayModePropertiesKHR&() const
     {
       return *reinterpret_cast<const VkDisplayModePropertiesKHR*>(this);
@@ -5419,7 +5361,8 @@
     eExportMemoryAllocateInfoNV = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV,
     eImportMemoryWin32HandleInfoNV = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV,
     eExportMemoryWin32HandleInfoNV = VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV,
-    eWin32KeyedMutexAcquireReleaseInfoNV = VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV
+    eWin32KeyedMutexAcquireReleaseInfoNV = VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV,
+    eValidationFlagsEXT = VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT
   };
 
   struct ApplicationInfo
@@ -9003,6 +8946,206 @@
 
   struct PresentInfoKHR
   {
+    ExportMemoryWin32HandleInfoNV( const SECURITY_ATTRIBUTES* pAttributes_ = nullptr, DWORD dwAccess_ = 0 )
+      : sType( StructureType::eExportMemoryWin32HandleInfoNV )
+      , pNext( nullptr )
+      , pAttributes( pAttributes_ )
+      , dwAccess( dwAccess_ )
+    {
+    }
+
+    ExportMemoryWin32HandleInfoNV( VkExportMemoryWin32HandleInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExportMemoryWin32HandleInfoNV) );
+    }
+
+    ExportMemoryWin32HandleInfoNV& operator=( VkExportMemoryWin32HandleInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExportMemoryWin32HandleInfoNV) );
+      return *this;
+    }
+
+    ExportMemoryWin32HandleInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ExportMemoryWin32HandleInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ExportMemoryWin32HandleInfoNV& setPAttributes( const SECURITY_ATTRIBUTES* pAttributes_ )
+    {
+      pAttributes = pAttributes_;
+      return *this;
+    }
+
+    ExportMemoryWin32HandleInfoNV& setDwAccess( DWORD dwAccess_ )
+    {
+      dwAccess = dwAccess_;
+      return *this;
+    }
+
+    operator const VkExportMemoryWin32HandleInfoNV&() const
+    {
+      return *reinterpret_cast<const VkExportMemoryWin32HandleInfoNV*>(this);
+    }
+
+    bool operator==( ExportMemoryWin32HandleInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( pAttributes == rhs.pAttributes )
+          && ( dwAccess == rhs.dwAccess );
+    }
+
+    bool operator!=( ExportMemoryWin32HandleInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    const SECURITY_ATTRIBUTES* pAttributes;
+    DWORD dwAccess;
+  };
+  static_assert( sizeof( ExportMemoryWin32HandleInfoNV ) == sizeof( VkExportMemoryWin32HandleInfoNV ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  struct Win32KeyedMutexAcquireReleaseInfoNV
+  {
+    Win32KeyedMutexAcquireReleaseInfoNV( uint32_t acquireCount_ = 0, const DeviceMemory* pAcquireSyncs_ = nullptr, const uint64_t* pAcquireKeys_ = nullptr, const uint32_t* pAcquireTimeoutMilliseconds_ = nullptr, uint32_t releaseCount_ = 0, const DeviceMemory* pReleaseSyncs_ = nullptr, const uint64_t* pReleaseKeys_ = nullptr )
+      : sType( StructureType::eWin32KeyedMutexAcquireReleaseInfoNV )
+      , pNext( nullptr )
+      , acquireCount( acquireCount_ )
+      , pAcquireSyncs( pAcquireSyncs_ )
+      , pAcquireKeys( pAcquireKeys_ )
+      , pAcquireTimeoutMilliseconds( pAcquireTimeoutMilliseconds_ )
+      , releaseCount( releaseCount_ )
+      , pReleaseSyncs( pReleaseSyncs_ )
+      , pReleaseKeys( pReleaseKeys_ )
+    {
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV( VkWin32KeyedMutexAcquireReleaseInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Win32KeyedMutexAcquireReleaseInfoNV) );
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& operator=( VkWin32KeyedMutexAcquireReleaseInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(Win32KeyedMutexAcquireReleaseInfoNV) );
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setAcquireCount( uint32_t acquireCount_ )
+    {
+      acquireCount = acquireCount_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPAcquireSyncs( const DeviceMemory* pAcquireSyncs_ )
+    {
+      pAcquireSyncs = pAcquireSyncs_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPAcquireKeys( const uint64_t* pAcquireKeys_ )
+    {
+      pAcquireKeys = pAcquireKeys_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPAcquireTimeoutMilliseconds( const uint32_t* pAcquireTimeoutMilliseconds_ )
+    {
+      pAcquireTimeoutMilliseconds = pAcquireTimeoutMilliseconds_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setReleaseCount( uint32_t releaseCount_ )
+    {
+      releaseCount = releaseCount_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPReleaseSyncs( const DeviceMemory* pReleaseSyncs_ )
+    {
+      pReleaseSyncs = pReleaseSyncs_;
+      return *this;
+    }
+
+    Win32KeyedMutexAcquireReleaseInfoNV& setPReleaseKeys( const uint64_t* pReleaseKeys_ )
+    {
+      pReleaseKeys = pReleaseKeys_;
+      return *this;
+    }
+
+    operator const VkWin32KeyedMutexAcquireReleaseInfoNV&() const
+    {
+      return *reinterpret_cast<const VkWin32KeyedMutexAcquireReleaseInfoNV*>(this);
+    }
+
+    bool operator==( Win32KeyedMutexAcquireReleaseInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( acquireCount == rhs.acquireCount )
+          && ( pAcquireSyncs == rhs.pAcquireSyncs )
+          && ( pAcquireKeys == rhs.pAcquireKeys )
+          && ( pAcquireTimeoutMilliseconds == rhs.pAcquireTimeoutMilliseconds )
+          && ( releaseCount == rhs.releaseCount )
+          && ( pReleaseSyncs == rhs.pReleaseSyncs )
+          && ( pReleaseKeys == rhs.pReleaseKeys );
+    }
+
+    bool operator!=( Win32KeyedMutexAcquireReleaseInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    uint32_t acquireCount;
+    const DeviceMemory* pAcquireSyncs;
+    const uint64_t* pAcquireKeys;
+    const uint32_t* pAcquireTimeoutMilliseconds;
+    uint32_t releaseCount;
+    const DeviceMemory* pReleaseSyncs;
+    const uint64_t* pReleaseKeys;
+  };
+  static_assert( sizeof( Win32KeyedMutexAcquireReleaseInfoNV ) == sizeof( VkWin32KeyedMutexAcquireReleaseInfoNV ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+  enum class SubpassContents
+  {
+    eInline = VK_SUBPASS_CONTENTS_INLINE,
+    eSecondaryCommandBuffers = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
+  };
+
+  struct PresentInfoKHR
+  {
     PresentInfoKHR( uint32_t waitSemaphoreCount_ = 0, const Semaphore* pWaitSemaphores_ = nullptr, uint32_t swapchainCount_ = 0, const SwapchainKHR* pSwapchains_ = nullptr, const uint32_t* pImageIndices_ = nullptr, Result* pResults_ = nullptr )
       : sType( StructureType::ePresentInfoKHR )
       , pNext( nullptr )
@@ -14817,35 +14960,6 @@
 
   struct SurfaceFormatKHR
   {
-    SurfaceFormatKHR( Format format_ = Format::eUndefined, ColorSpaceKHR colorSpace_ = ColorSpaceKHR::eSrgbNonlinear )
-      : format( format_ )
-      , colorSpace( colorSpace_ )
-    {
-    }
-
-    SurfaceFormatKHR( VkSurfaceFormatKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(SurfaceFormatKHR) );
-    }
-
-    SurfaceFormatKHR& operator=( VkSurfaceFormatKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(SurfaceFormatKHR) );
-      return *this;
-    }
-
-    SurfaceFormatKHR& setFormat( Format format_ )
-    {
-      format = format_;
-      return *this;
-    }
-
-    SurfaceFormatKHR& setColorSpace( ColorSpaceKHR colorSpace_ )
-    {
-      colorSpace = colorSpace_;
-      return *this;
-    }
-
     operator const VkSurfaceFormatKHR&() const
     {
       return *reinterpret_cast<const VkSurfaceFormatKHR*>(this);
@@ -14884,84 +14998,6 @@
 
   struct DisplayPlaneCapabilitiesKHR
   {
-    DisplayPlaneCapabilitiesKHR( DisplayPlaneAlphaFlagsKHR supportedAlpha_ = DisplayPlaneAlphaFlagsKHR(), Offset2D minSrcPosition_ = Offset2D(), Offset2D maxSrcPosition_ = Offset2D(), Extent2D minSrcExtent_ = Extent2D(), Extent2D maxSrcExtent_ = Extent2D(), Offset2D minDstPosition_ = Offset2D(), Offset2D maxDstPosition_ = Offset2D(), Extent2D minDstExtent_ = Extent2D(), Extent2D maxDstExtent_ = Extent2D() )
-      : supportedAlpha( supportedAlpha_ )
-      , minSrcPosition( minSrcPosition_ )
-      , maxSrcPosition( maxSrcPosition_ )
-      , minSrcExtent( minSrcExtent_ )
-      , maxSrcExtent( maxSrcExtent_ )
-      , minDstPosition( minDstPosition_ )
-      , maxDstPosition( maxDstPosition_ )
-      , minDstExtent( minDstExtent_ )
-      , maxDstExtent( maxDstExtent_ )
-    {
-    }
-
-    DisplayPlaneCapabilitiesKHR( VkDisplayPlaneCapabilitiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPlaneCapabilitiesKHR) );
-    }
-
-    DisplayPlaneCapabilitiesKHR& operator=( VkDisplayPlaneCapabilitiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPlaneCapabilitiesKHR) );
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setSupportedAlpha( DisplayPlaneAlphaFlagsKHR supportedAlpha_ )
-    {
-      supportedAlpha = supportedAlpha_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMinSrcPosition( Offset2D minSrcPosition_ )
-    {
-      minSrcPosition = minSrcPosition_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMaxSrcPosition( Offset2D maxSrcPosition_ )
-    {
-      maxSrcPosition = maxSrcPosition_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMinSrcExtent( Extent2D minSrcExtent_ )
-    {
-      minSrcExtent = minSrcExtent_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMaxSrcExtent( Extent2D maxSrcExtent_ )
-    {
-      maxSrcExtent = maxSrcExtent_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMinDstPosition( Offset2D minDstPosition_ )
-    {
-      minDstPosition = minDstPosition_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMaxDstPosition( Offset2D maxDstPosition_ )
-    {
-      maxDstPosition = maxDstPosition_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMinDstExtent( Extent2D minDstExtent_ )
-    {
-      minDstExtent = minDstExtent_;
-      return *this;
-    }
-
-    DisplayPlaneCapabilitiesKHR& setMaxDstExtent( Extent2D maxDstExtent_ )
-    {
-      maxDstExtent = maxDstExtent_;
-      return *this;
-    }
-
     operator const VkDisplayPlaneCapabilitiesKHR&() const
     {
       return *reinterpret_cast<const VkDisplayPlaneCapabilitiesKHR*>(this);
@@ -15034,70 +15070,6 @@
 
   struct DisplayPropertiesKHR
   {
-    DisplayPropertiesKHR( DisplayKHR display_ = DisplayKHR(), const char* displayName_ = nullptr, Extent2D physicalDimensions_ = Extent2D(), Extent2D physicalResolution_ = Extent2D(), SurfaceTransformFlagsKHR supportedTransforms_ = SurfaceTransformFlagsKHR(), Bool32 planeReorderPossible_ = 0, Bool32 persistentContent_ = 0 )
-      : display( display_ )
-      , displayName( displayName_ )
-      , physicalDimensions( physicalDimensions_ )
-      , physicalResolution( physicalResolution_ )
-      , supportedTransforms( supportedTransforms_ )
-      , planeReorderPossible( planeReorderPossible_ )
-      , persistentContent( persistentContent_ )
-    {
-    }
-
-    DisplayPropertiesKHR( VkDisplayPropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPropertiesKHR) );
-    }
-
-    DisplayPropertiesKHR& operator=( VkDisplayPropertiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(DisplayPropertiesKHR) );
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setDisplay( DisplayKHR display_ )
-    {
-      display = display_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setDisplayName( const char* displayName_ )
-    {
-      displayName = displayName_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setPhysicalDimensions( Extent2D physicalDimensions_ )
-    {
-      physicalDimensions = physicalDimensions_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setPhysicalResolution( Extent2D physicalResolution_ )
-    {
-      physicalResolution = physicalResolution_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setSupportedTransforms( SurfaceTransformFlagsKHR supportedTransforms_ )
-    {
-      supportedTransforms = supportedTransforms_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setPlaneReorderPossible( Bool32 planeReorderPossible_ )
-    {
-      planeReorderPossible = planeReorderPossible_;
-      return *this;
-    }
-
-    DisplayPropertiesKHR& setPersistentContent( Bool32 persistentContent_ )
-    {
-      persistentContent = persistentContent_;
-      return *this;
-    }
-
     operator const VkDisplayPropertiesKHR&() const
     {
       return *reinterpret_cast<const VkDisplayPropertiesKHR*>(this);
@@ -15258,91 +15230,6 @@
 
   struct SurfaceCapabilitiesKHR
   {
-    SurfaceCapabilitiesKHR( uint32_t minImageCount_ = 0, uint32_t maxImageCount_ = 0, Extent2D currentExtent_ = Extent2D(), Extent2D minImageExtent_ = Extent2D(), Extent2D maxImageExtent_ = Extent2D(), uint32_t maxImageArrayLayers_ = 0, SurfaceTransformFlagsKHR supportedTransforms_ = SurfaceTransformFlagsKHR(), SurfaceTransformFlagBitsKHR currentTransform_ = SurfaceTransformFlagBitsKHR::eIdentity, CompositeAlphaFlagsKHR supportedCompositeAlpha_ = CompositeAlphaFlagsKHR(), ImageUsageFlags supportedUsageFlags_ = ImageUsageFlags() )
-      : minImageCount( minImageCount_ )
-      , maxImageCount( maxImageCount_ )
-      , currentExtent( currentExtent_ )
-      , minImageExtent( minImageExtent_ )
-      , maxImageExtent( maxImageExtent_ )
-      , maxImageArrayLayers( maxImageArrayLayers_ )
-      , supportedTransforms( supportedTransforms_ )
-      , currentTransform( currentTransform_ )
-      , supportedCompositeAlpha( supportedCompositeAlpha_ )
-      , supportedUsageFlags( supportedUsageFlags_ )
-    {
-    }
-
-    SurfaceCapabilitiesKHR( VkSurfaceCapabilitiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(SurfaceCapabilitiesKHR) );
-    }
-
-    SurfaceCapabilitiesKHR& operator=( VkSurfaceCapabilitiesKHR const & rhs )
-    {
-      memcpy( this, &rhs, sizeof(SurfaceCapabilitiesKHR) );
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setMinImageCount( uint32_t minImageCount_ )
-    {
-      minImageCount = minImageCount_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setMaxImageCount( uint32_t maxImageCount_ )
-    {
-      maxImageCount = maxImageCount_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setCurrentExtent( Extent2D currentExtent_ )
-    {
-      currentExtent = currentExtent_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setMinImageExtent( Extent2D minImageExtent_ )
-    {
-      minImageExtent = minImageExtent_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setMaxImageExtent( Extent2D maxImageExtent_ )
-    {
-      maxImageExtent = maxImageExtent_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setMaxImageArrayLayers( uint32_t maxImageArrayLayers_ )
-    {
-      maxImageArrayLayers = maxImageArrayLayers_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setSupportedTransforms( SurfaceTransformFlagsKHR supportedTransforms_ )
-    {
-      supportedTransforms = supportedTransforms_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setCurrentTransform( SurfaceTransformFlagBitsKHR currentTransform_ )
-    {
-      currentTransform = currentTransform_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setSupportedCompositeAlpha( CompositeAlphaFlagsKHR supportedCompositeAlpha_ )
-    {
-      supportedCompositeAlpha = supportedCompositeAlpha_;
-      return *this;
-    }
-
-    SurfaceCapabilitiesKHR& setSupportedUsageFlags( ImageUsageFlags supportedUsageFlags_ )
-    {
-      supportedUsageFlags = supportedUsageFlags_;
-      return *this;
-    }
-
     operator const VkSurfaceCapabilitiesKHR&() const
     {
       return *reinterpret_cast<const VkSurfaceCapabilitiesKHR*>(this);
@@ -15985,6 +15872,112 @@
 
   class Device
   {
+    eNone = VK_DEBUG_REPORT_ERROR_NONE_EXT,
+    eCallbackRef = VK_DEBUG_REPORT_ERROR_CALLBACK_REF_EXT
+  };
+
+  enum class RasterizationOrderAMD
+  {
+    eStrict = VK_RASTERIZATION_ORDER_STRICT_AMD,
+    eRelaxed = VK_RASTERIZATION_ORDER_RELAXED_AMD
+  };
+
+  struct PipelineRasterizationStateRasterizationOrderAMD
+  {
+    PipelineRasterizationStateRasterizationOrderAMD( RasterizationOrderAMD rasterizationOrder_ = RasterizationOrderAMD::eStrict )
+      : sType( StructureType::ePipelineRasterizationStateRasterizationOrderAMD )
+      , pNext( nullptr )
+      , rasterizationOrder( rasterizationOrder_ )
+    {
+    }
+
+    bool operator==(Device const &rhs) const
+    {
+      return m_device == rhs.m_device;
+    }
+
+    bool operator!=(Device const &rhs) const
+    {
+      return m_device != rhs.m_device;
+    }
+
+    bool operator<(Device const &rhs) const
+    {
+      return m_device < rhs.m_device;
+    }
+
+    PFN_vkVoidFunction getProcAddr( const char* pName ) const
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateRasterizationOrderAMD) );
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& operator=( VkPipelineRasterizationStateRasterizationOrderAMD const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(PipelineRasterizationStateRasterizationOrderAMD) );
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    PipelineRasterizationStateRasterizationOrderAMD& setRasterizationOrder( RasterizationOrderAMD rasterizationOrder_ )
+    {
+      rasterizationOrder = rasterizationOrder_;
+      return *this;
+    }
+
+    operator const VkPipelineRasterizationStateRasterizationOrderAMD&() const
+    {
+      return *reinterpret_cast<const VkPipelineRasterizationStateRasterizationOrderAMD*>(this);
+    }
+
+    bool operator==( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( rasterizationOrder == rhs.rasterizationOrder );
+    }
+
+    bool operator!=( PipelineRasterizationStateRasterizationOrderAMD const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    RasterizationOrderAMD rasterizationOrder;
+  };
+  static_assert( sizeof( PipelineRasterizationStateRasterizationOrderAMD ) == sizeof( VkPipelineRasterizationStateRasterizationOrderAMD ), "struct and wrapper have different size!" );
+
+  enum class ExternalMemoryHandleTypeFlagBitsNV
+  {
+    eOpaqueWin32 = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_NV,
+    eOpaqueWin32Kmt = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT_NV,
+    eD3D11Image = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_BIT_NV,
+    eD3D11ImageKmt = VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_IMAGE_KMT_BIT_NV
+  };
+
+  using ExternalMemoryHandleTypeFlagsNV = Flags<ExternalMemoryHandleTypeFlagBitsNV, VkExternalMemoryHandleTypeFlagsNV>;
+
+  inline ExternalMemoryHandleTypeFlagsNV operator|( ExternalMemoryHandleTypeFlagBitsNV bit0, ExternalMemoryHandleTypeFlagBitsNV bit1 )
+  {
+    return ExternalMemoryHandleTypeFlagsNV( bit0 ) | bit1;
+  }
+
+  class Device
+  {
   public:
     Device()
       : m_device(VK_NULL_HANDLE)
@@ -17450,6 +17443,293 @@
   };
   static_assert( sizeof( ExternalImageFormatPropertiesNV ) == sizeof( VkExternalImageFormatPropertiesNV ), "struct and wrapper have different size!" );
 
+  struct ExternalMemoryImageCreateInfoNV
+  {
+    ExternalMemoryImageCreateInfoNV( ExternalMemoryHandleTypeFlagsNV handleTypes_ = ExternalMemoryHandleTypeFlagsNV() )
+      : sType( StructureType::eExternalMemoryImageCreateInfoNV )
+      , pNext( nullptr )
+      , handleTypes( handleTypes_ )
+    {
+    }
+
+    ExternalMemoryImageCreateInfoNV( VkExternalMemoryImageCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExternalMemoryImageCreateInfoNV) );
+    }
+
+    ExternalMemoryImageCreateInfoNV& operator=( VkExternalMemoryImageCreateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExternalMemoryImageCreateInfoNV) );
+      return *this;
+    }
+
+    ExternalMemoryImageCreateInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ExternalMemoryImageCreateInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ExternalMemoryImageCreateInfoNV& setHandleTypes( ExternalMemoryHandleTypeFlagsNV handleTypes_ )
+    {
+      handleTypes = handleTypes_;
+      return *this;
+    }
+
+    operator const VkExternalMemoryImageCreateInfoNV&() const
+    {
+      return *reinterpret_cast<const VkExternalMemoryImageCreateInfoNV*>(this);
+    }
+
+    bool operator==( ExternalMemoryImageCreateInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( handleTypes == rhs.handleTypes );
+    }
+
+    bool operator!=( ExternalMemoryImageCreateInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ExternalMemoryHandleTypeFlagsNV handleTypes;
+  };
+  static_assert( sizeof( ExternalMemoryImageCreateInfoNV ) == sizeof( VkExternalMemoryImageCreateInfoNV ), "struct and wrapper have different size!" );
+
+  struct ExportMemoryAllocateInfoNV
+  {
+    ExportMemoryAllocateInfoNV( ExternalMemoryHandleTypeFlagsNV handleTypes_ = ExternalMemoryHandleTypeFlagsNV() )
+      : sType( StructureType::eExportMemoryAllocateInfoNV )
+      , pNext( nullptr )
+      , handleTypes( handleTypes_ )
+    {
+    }
+
+    ExportMemoryAllocateInfoNV( VkExportMemoryAllocateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExportMemoryAllocateInfoNV) );
+    }
+
+    ExportMemoryAllocateInfoNV& operator=( VkExportMemoryAllocateInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExportMemoryAllocateInfoNV) );
+      return *this;
+    }
+
+    ExportMemoryAllocateInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ExportMemoryAllocateInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ExportMemoryAllocateInfoNV& setHandleTypes( ExternalMemoryHandleTypeFlagsNV handleTypes_ )
+    {
+      handleTypes = handleTypes_;
+      return *this;
+    }
+
+    operator const VkExportMemoryAllocateInfoNV&() const
+    {
+      return *reinterpret_cast<const VkExportMemoryAllocateInfoNV*>(this);
+    }
+
+    bool operator==( ExportMemoryAllocateInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( handleTypes == rhs.handleTypes );
+    }
+
+    bool operator!=( ExportMemoryAllocateInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ExternalMemoryHandleTypeFlagsNV handleTypes;
+  };
+  static_assert( sizeof( ExportMemoryAllocateInfoNV ) == sizeof( VkExportMemoryAllocateInfoNV ), "struct and wrapper have different size!" );
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+  struct ImportMemoryWin32HandleInfoNV
+  {
+    ImportMemoryWin32HandleInfoNV( ExternalMemoryHandleTypeFlagsNV handleType_ = ExternalMemoryHandleTypeFlagsNV(), HANDLE handle_ = 0 )
+      : sType( StructureType::eImportMemoryWin32HandleInfoNV )
+      , pNext( nullptr )
+      , handleType( handleType_ )
+      , handle( handle_ )
+    {
+    }
+
+    ImportMemoryWin32HandleInfoNV( VkImportMemoryWin32HandleInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImportMemoryWin32HandleInfoNV) );
+    }
+
+    ImportMemoryWin32HandleInfoNV& operator=( VkImportMemoryWin32HandleInfoNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ImportMemoryWin32HandleInfoNV) );
+      return *this;
+    }
+
+    ImportMemoryWin32HandleInfoNV& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ImportMemoryWin32HandleInfoNV& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ImportMemoryWin32HandleInfoNV& setHandleType( ExternalMemoryHandleTypeFlagsNV handleType_ )
+    {
+      handleType = handleType_;
+      return *this;
+    }
+
+    ImportMemoryWin32HandleInfoNV& setHandle( HANDLE handle_ )
+    {
+      handle = handle_;
+      return *this;
+    }
+
+    operator const VkImportMemoryWin32HandleInfoNV&() const
+    {
+      return *reinterpret_cast<const VkImportMemoryWin32HandleInfoNV*>(this);
+    }
+
+    bool operator==( ImportMemoryWin32HandleInfoNV const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( handleType == rhs.handleType )
+          && ( handle == rhs.handle );
+    }
+
+    bool operator!=( ImportMemoryWin32HandleInfoNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    ExternalMemoryHandleTypeFlagsNV handleType;
+    HANDLE handle;
+  };
+  static_assert( sizeof( ImportMemoryWin32HandleInfoNV ) == sizeof( VkImportMemoryWin32HandleInfoNV ), "struct and wrapper have different size!" );
+#endif /*VK_USE_PLATFORM_WIN32_KHR*/
+
+  enum class ExternalMemoryFeatureFlagBitsNV
+  {
+    eDedicatedOnly = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_NV,
+    eExportable = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV,
+    eImportable = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV
+  };
+
+  using ExternalMemoryFeatureFlagsNV = Flags<ExternalMemoryFeatureFlagBitsNV, VkExternalMemoryFeatureFlagsNV>;
+
+  inline ExternalMemoryFeatureFlagsNV operator|( ExternalMemoryFeatureFlagBitsNV bit0, ExternalMemoryFeatureFlagBitsNV bit1 )
+  {
+    return ExternalMemoryFeatureFlagsNV( bit0 ) | bit1;
+  }
+
+  struct ExternalImageFormatPropertiesNV
+  {
+    ExternalImageFormatPropertiesNV( ImageFormatProperties imageFormatProperties_ = ImageFormatProperties(), ExternalMemoryFeatureFlagsNV externalMemoryFeatures_ = ExternalMemoryFeatureFlagsNV(), ExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes_ = ExternalMemoryHandleTypeFlagsNV(), ExternalMemoryHandleTypeFlagsNV compatibleHandleTypes_ = ExternalMemoryHandleTypeFlagsNV() )
+      : imageFormatProperties( imageFormatProperties_ )
+      , externalMemoryFeatures( externalMemoryFeatures_ )
+      , exportFromImportedHandleTypes( exportFromImportedHandleTypes_ )
+      , compatibleHandleTypes( compatibleHandleTypes_ )
+    {
+    }
+
+    ExternalImageFormatPropertiesNV( VkExternalImageFormatPropertiesNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExternalImageFormatPropertiesNV) );
+    }
+
+    ExternalImageFormatPropertiesNV& operator=( VkExternalImageFormatPropertiesNV const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ExternalImageFormatPropertiesNV) );
+      return *this;
+    }
+
+    ExternalImageFormatPropertiesNV& setImageFormatProperties( ImageFormatProperties imageFormatProperties_ )
+    {
+      imageFormatProperties = imageFormatProperties_;
+      return *this;
+    }
+
+    ExternalImageFormatPropertiesNV& setExternalMemoryFeatures( ExternalMemoryFeatureFlagsNV externalMemoryFeatures_ )
+    {
+      externalMemoryFeatures = externalMemoryFeatures_;
+      return *this;
+    }
+
+    ExternalImageFormatPropertiesNV& setExportFromImportedHandleTypes( ExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes_ )
+    {
+      exportFromImportedHandleTypes = exportFromImportedHandleTypes_;
+      return *this;
+    }
+
+    ExternalImageFormatPropertiesNV& setCompatibleHandleTypes( ExternalMemoryHandleTypeFlagsNV compatibleHandleTypes_ )
+    {
+      compatibleHandleTypes = compatibleHandleTypes_;
+      return *this;
+    }
+
+    operator const VkExternalImageFormatPropertiesNV&() const
+    {
+      return *reinterpret_cast<const VkExternalImageFormatPropertiesNV*>(this);
+    }
+
+    bool operator==( ExternalImageFormatPropertiesNV const& rhs ) const
+    {
+      return ( imageFormatProperties == rhs.imageFormatProperties )
+          && ( externalMemoryFeatures == rhs.externalMemoryFeatures )
+          && ( exportFromImportedHandleTypes == rhs.exportFromImportedHandleTypes )
+          && ( compatibleHandleTypes == rhs.compatibleHandleTypes );
+    }
+
+    bool operator!=( ExternalImageFormatPropertiesNV const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+    ImageFormatProperties imageFormatProperties;
+    ExternalMemoryFeatureFlagsNV externalMemoryFeatures;
+    ExternalMemoryHandleTypeFlagsNV exportFromImportedHandleTypes;
+    ExternalMemoryHandleTypeFlagsNV compatibleHandleTypes;
+  };
+  static_assert( sizeof( ExternalImageFormatPropertiesNV ) == sizeof( VkExternalImageFormatPropertiesNV ), "struct and wrapper have different size!" );
+
   class PhysicalDevice
   {
   public:
@@ -18275,6 +18555,84 @@
   };
   static_assert( sizeof( Instance ) == sizeof( VkInstance ), "handle and wrapper have different size!" );
 
+  enum class ValidationCheckEXT
+  {
+    eAll = VK_VALIDATION_CHECK_ALL_EXT
+  };
+
+  struct ValidationFlagsEXT
+  {
+    ValidationFlagsEXT( uint32_t disabledValidationCheckCount_ = 0, ValidationCheckEXT* pDisabledValidationChecks_ = nullptr )
+      : sType( StructureType::eValidationFlagsEXT )
+      , pNext( nullptr )
+      , disabledValidationCheckCount( disabledValidationCheckCount_ )
+      , pDisabledValidationChecks( pDisabledValidationChecks_ )
+    {
+    }
+
+    ValidationFlagsEXT( VkValidationFlagsEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ValidationFlagsEXT) );
+    }
+
+    ValidationFlagsEXT& operator=( VkValidationFlagsEXT const & rhs )
+    {
+      memcpy( this, &rhs, sizeof(ValidationFlagsEXT) );
+      return *this;
+    }
+
+    ValidationFlagsEXT& setSType( StructureType sType_ )
+    {
+      sType = sType_;
+      return *this;
+    }
+
+    ValidationFlagsEXT& setPNext( const void* pNext_ )
+    {
+      pNext = pNext_;
+      return *this;
+    }
+
+    ValidationFlagsEXT& setDisabledValidationCheckCount( uint32_t disabledValidationCheckCount_ )
+    {
+      disabledValidationCheckCount = disabledValidationCheckCount_;
+      return *this;
+    }
+
+    ValidationFlagsEXT& setPDisabledValidationChecks( ValidationCheckEXT* pDisabledValidationChecks_ )
+    {
+      pDisabledValidationChecks = pDisabledValidationChecks_;
+      return *this;
+    }
+
+    operator const VkValidationFlagsEXT&() const
+    {
+      return *reinterpret_cast<const VkValidationFlagsEXT*>(this);
+    }
+
+    bool operator==( ValidationFlagsEXT const& rhs ) const
+    {
+      return ( sType == rhs.sType )
+          && ( pNext == rhs.pNext )
+          && ( disabledValidationCheckCount == rhs.disabledValidationCheckCount )
+          && ( pDisabledValidationChecks == rhs.pDisabledValidationChecks );
+    }
+
+    bool operator!=( ValidationFlagsEXT const& rhs ) const
+    {
+      return !operator==( rhs );
+    }
+
+  private:
+    StructureType sType;
+
+  public:
+    const void* pNext;
+    uint32_t disabledValidationCheckCount;
+    ValidationCheckEXT* pDisabledValidationChecks;
+  };
+  static_assert( sizeof( ValidationFlagsEXT ) == sizeof( VkValidationFlagsEXT ), "struct and wrapper have different size!" );
+
   inline Result createInstance( const InstanceCreateInfo* pCreateInfo, const AllocationCallbacks* pAllocator, Instance* pInstance )
   {
     return static_cast<Result>( vkCreateInstance( reinterpret_cast<const VkInstanceCreateInfo*>( pCreateInfo ), reinterpret_cast<const VkAllocationCallbacks*>( pAllocator ), reinterpret_cast<VkInstance*>( pInstance ) ) );
@@ -19436,6 +19794,7 @@
     case StructureType::eImportMemoryWin32HandleInfoNV: return "ImportMemoryWin32HandleInfoNV";
     case StructureType::eExportMemoryWin32HandleInfoNV: return "ExportMemoryWin32HandleInfoNV";
     case StructureType::eWin32KeyedMutexAcquireReleaseInfoNV: return "Win32KeyedMutexAcquireReleaseInfoNV";
+    case StructureType::eValidationFlagsEXT: return "ValidationFlagsEXT";
     default: return "invalid";
     }
   }
@@ -20414,6 +20773,15 @@
     return "{" + result.substr(0, result.size() - 3) + "}";
   }
 
+  inline std::string to_string(ValidationCheckEXT value)
+  {
+    switch (value)
+    {
+    case ValidationCheckEXT::eAll: return "All";
+    default: return "invalid";
+    }
+  }
+
 } // namespace vk
 
 #endif
diff --git a/layers/CMakeLists.txt b/layers/CMakeLists.txt
index 456844f..711da11 100644
--- a/layers/CMakeLists.txt
+++ b/layers/CMakeLists.txt
@@ -7,19 +7,13 @@
     )
 endmacro()
 
-macro(run_vk_layer_generate subcmd output)
+macro(run_vk_layer_xml_generate dependency output)
     add_custom_command(OUTPUT ${output}
-        COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-layer-generate.py ${DisplayServer} ${subcmd} ${PROJECT_SOURCE_DIR}/include/vulkan/vulkan.h > ${output}
-        DEPENDS ${PROJECT_SOURCE_DIR}/vk-layer-generate.py ${PROJECT_SOURCE_DIR}/include/vulkan/vulkan.h ${PROJECT_SOURCE_DIR}/vulkan.py
+        COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/lvl_genvk.py -registry ${PROJECT_SOURCE_DIR}/vk.xml ${output}
+        DEPENDS ${PROJECT_SOURCE_DIR}/vk.xml ${PROJECT_SOURCE_DIR}/generator.py ${PROJECT_SOURCE_DIR}/${dependency} ${PROJECT_SOURCE_DIR}/lvl_genvk.py ${PROJECT_SOURCE_DIR}/reg.py
     )
 endmacro()
 
-macro(run_vk_layer_xml_generate subcmd output)
-    add_custom_command(OUTPUT ${output}
-        COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/genvk.py -registry ${PROJECT_SOURCE_DIR}/vk.xml ${output}
-        DEPENDS ${PROJECT_SOURCE_DIR}/vk.xml ${PROJECT_SOURCE_DIR}/generator.py ${PROJECT_SOURCE_DIR}/genvk.py ${PROJECT_SOURCE_DIR}/reg.py
-    )
-endmacro()
 set(LAYER_JSON_FILES
     VkLayer_core_validation
     VkLayer_image
@@ -40,6 +34,7 @@
                     COMMAND copy ${src_json} ${dst_json}
                     VERBATIM
                     )
+                add_dependencies(${config_file}-json ${config_file})
             endforeach(config_file)
         else()
             foreach (config_file ${LAYER_JSON_FILES})
@@ -49,6 +44,7 @@
                     COMMAND copy ${src_json} ${dst_json}
                     VERBATIM
                     )
+                add_dependencies(${config_file}-json ${config_file})
             endforeach(config_file)
         endif()
     endif()
@@ -60,10 +56,26 @@
                 COMMAND ln -sf ${CMAKE_CURRENT_SOURCE_DIR}/linux/${config_file}.json
                 VERBATIM
                 )
+                add_dependencies(${config_file}-json ${config_file})
         endforeach(config_file)
     endif()
 endif()
 
+# Add targets for JSON file install on Linux.
+# Need to remove the "./" from the library path before installing to /etc.
+if(UNIX)
+    foreach (config_file ${LAYER_JSON_FILES})
+        add_custom_target(${config_file}-staging-json ALL
+            COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/staging-json
+            COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/linux/${config_file}.json ${CMAKE_CURRENT_BINARY_DIR}/staging-json
+            COMMAND sed -i -e "/\"library_path\":/s$./libVkLayer$libVkLayer$" ${CMAKE_CURRENT_BINARY_DIR}/staging-json/${config_file}.json
+            VERBATIM
+            DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linux/${config_file}.json
+            )
+        install(FILES ${CMAKE_CURRENT_BINARY_DIR}/staging-json/${config_file}.json DESTINATION /etc/vulkan/explicit_layer.d)
+    endforeach(config_file)
+endif()
+
 if (WIN32)
     macro(add_vk_layer target)
     add_custom_command(OUTPUT VkLayer_${target}.def
@@ -72,16 +84,15 @@
     )
     add_library(VkLayer_${target} SHARED ${ARGN} VkLayer_${target}.def)
     target_link_Libraries(VkLayer_${target} VkLayer_utils)
-    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
-    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/VkLayer_${target}.def")
+    add_dependencies(VkLayer_${target} generate_dispatch_table_helper generate_vk_layer_helpers generate_enum_string_helper VkLayer_utils)
     endmacro()
 else()
     macro(add_vk_layer target)
     add_library(VkLayer_${target} SHARED ${ARGN})
     target_link_Libraries(VkLayer_${target} VkLayer_utils)
-    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
-    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic")
-    install(TARGETS VkLayer_${target} DESTINATION ${PROJECT_BINARY_DIR}/install_staging)
+    add_dependencies(VkLayer_${target} generate_dispatch_table_helper generate_vk_layer_helpers generate_enum_string_helper VkLayer_utils)
+    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,--exclude-libs,ALL")
+    install(TARGETS VkLayer_${target} DESTINATION lib)
     endmacro()
 endif()
 
@@ -98,8 +109,8 @@
     set (CMAKE_CXX_FLAGS_DEBUG   "${CMAKE_CXX_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
     set (CMAKE_C_FLAGS_DEBUG     "${CMAKE_C_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
 else()
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpointer-arith -Wno-unused-function -Wno-sign-compare -fvisibility=default")
-    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wno-unused-function -Wno-sign-compare -fvisibility=default")
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpointer-arith -Wno-unused-function -Wno-sign-compare")
+    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wno-unused-function -Wno-sign-compare")
 endif()
 
 add_custom_command(OUTPUT vk_dispatch_table_helper.h
@@ -117,12 +128,40 @@
     vk_struct_wrappers.h
     vk_struct_wrappers.cpp
     vk_safe_struct.h
+# Don't list vk_safe_struct.cpp as OUTPUT to avoid duplicate builds.
+# If listed here use of it for add_library will cause it to be created
+# independently of custom target generate_vk_layer_helpers .
+# That breaks parallel builds.
+#   vk_safe_struct.cpp
+)
+
+# Let gen_struct_wrappers really create vk_safe_struct.cpp
+add_custom_command(OUTPUT vk_safe_struct.cpp
+    COMMAND echo defer making vk_safe_struct.cpp
+)
+
+set_source_files_properties(
+    vk_struct_string_helper.h
+    vk_struct_string_helper_cpp.h
+    vk_struct_string_helper_no_addr.h
+    vk_struct_string_helper_no_addr_cpp.h
+    vk_struct_size_helper.h
+    vk_struct_size_helper.c
+    vk_struct_wrappers.h
+    vk_struct_wrappers.cpp
+    vk_safe_struct.h
     vk_safe_struct.cpp
+    PROPERTIES GENERATED TRUE)
+
+add_custom_target(generate_enum_string_helper DEPENDS
+    vk_enum_string_helper.h
+)
+
+add_custom_target(generate_dispatch_table_helper DEPENDS
+    vk_dispatch_table_helper.h
 )
 
 add_custom_target(generate_vk_layer_helpers DEPENDS
-    vk_dispatch_table_helper.h
-    vk_enum_string_helper.h
     vk_struct_string_helper.h
     vk_struct_string_helper_no_addr.h
     vk_struct_string_helper_cpp.h
@@ -135,9 +174,9 @@
     vk_safe_struct.cpp
 )
 
-run_vk_layer_xml_generate(Threading thread_check.h)
-run_vk_layer_generate(unique_objects unique_objects.cpp)
-run_vk_layer_xml_generate(ParamChecker parameter_validation.h)
+run_vk_layer_xml_generate(threading_generator.py thread_check.h)
+run_vk_layer_xml_generate(parameter_validation_generator.py parameter_validation.h)
+run_vk_layer_xml_generate(unique_objects_generator.py unique_objects_wrappers.h)
 
 # Layer Utils Library
 # For Windows, we use a static lib because the Windows loader has a fairly restrictive loader search
@@ -146,7 +185,7 @@
     add_library(VkLayer_utils STATIC vk_layer_config.cpp vk_layer_extension_utils.cpp vk_layer_utils.cpp)
 else()
     add_library(VkLayer_utils SHARED vk_layer_config.cpp vk_layer_extension_utils.cpp vk_layer_utils.cpp)
-    install(TARGETS VkLayer_utils DESTINATION ${PROJECT_BINARY_DIR}/install_staging)
+    install(TARGETS VkLayer_utils DESTINATION lib)
 endif()
 
 add_vk_layer(core_validation core_validation.cpp vk_layer_table.cpp vk_safe_struct.cpp descriptor_sets.cpp)
@@ -155,7 +194,7 @@
 add_vk_layer(swapchain swapchain.cpp vk_layer_table.cpp)
 # generated
 add_vk_layer(threading threading.cpp thread_check.h vk_layer_table.cpp)
-add_vk_layer(unique_objects unique_objects.cpp vk_layer_table.cpp vk_safe_struct.cpp)
+add_vk_layer(unique_objects unique_objects.cpp unique_objects_wrappers.h vk_layer_table.cpp vk_safe_struct.cpp)
 add_vk_layer(parameter_validation parameter_validation.cpp parameter_validation.h vk_layer_table.cpp)
 
 # Core validation has additional dependencies
diff --git a/layers/README.md b/layers/README.md
index b496e75..8de8f18 100644
--- a/layers/README.md
+++ b/layers/README.md
@@ -21,13 +21,14 @@
 Layers can also be activated via the VK_INSTANCE_LAYERS environment variable.
 
 All validation layers work with the DEBUG_REPORT extension to provide validation feedback.
-When a validation layer is enabled, it will look for a vk_layer_settings.txt file to define
-its logging behavior, which can include sending output to a file, stdout, or debug output (Windows).
-Applications can also register debug callback functions via the DEBUG_REPORT extension to receive
-callbacks when validation events occur. Application callbacks are independent of settings in a
-vk_layer_settings.txt file which will be carried out separately. If no vk_layer_settings.txt
-file is present and no application callbacks are registered, error messages will be output
-through default logging callbacks.
+When a validation layer is enabled, it will look for a vk_layer_settings.txt file (see"Using
+Layers" section below for more details) to define its logging behavior, which can include
+sending output to a file, stdout, or debug output (Windows). Applications can also register
+debug callback functions via the DEBUG_REPORT extension to receive callbacks when validation
+events occur. Application callbacks are independent of settings in a vk_layer_settings.txt
+file which will be carried out separately. If no vk_layer_settings.txt file is present and
+no application callbacks are registered, error messages will be output through default
+logging callbacks.
 
 ### Layer library example code
 
@@ -72,9 +73,9 @@
     This is required for the Loader to be able to scan and enumerate your library.
     Alternatively, use the `VK_LAYER_PATH` environment variable to specify where the layer libraries reside.
 
-3. Create a vk_layer_settings.txt file in the same directory to specify how your layers should behave.
+3. To specify how your layers should behave, create a vk_layer_settings.txt file. This file can exist in the same directory as your app or in a directory given by the `VK_LAYER_SETTINGS_PATH` environment variable. Alternatively, you can use any filename you want if you set `VK_LAYER_SETTINGS_PATH` to the full path of the file, rather than the directory that contains it.
 
-    Model it after the following example:  [*vk_layer_settings.txt*](vk_layer_settings.txt)
+    Model the file after the following example:  [*vk_layer_settings.txt*](vk_layer_settings.txt)
 
 4. Specify which layers to activate using environment variables.
 
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 0030793..b4b080a 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -27,9 +27,6 @@
 // Allow use of STL min and max functions in Windows
 #define NOMINMAX
 
-// Turn on mem_tracker merged code
-#define MTMERGESOURCE 1
-
 #include <SPIRV/spirv.hpp>
 #include <algorithm>
 #include <assert.h>
@@ -83,6 +80,8 @@
 // WSI Image Objects bypass usual Image Object creation methods.  A special Memory
 // Object value will be used to identify them internally.
 static const VkDeviceMemory MEMTRACKER_SWAP_CHAIN_IMAGE_KEY = (VkDeviceMemory)(-1);
+// 2nd special memory handle used to flag object as unbound from memory
+static const VkDeviceMemory MEMORY_UNBOUND = VkDeviceMemory(~((uint64_t)(0)) - 1);
 
 struct devExts {
     bool wsi_enabled;
@@ -94,64 +93,87 @@
 // fwd decls
 struct shader_module;
 
-// TODO : Split this into separate structs for instance and device level data?
-struct layer_data {
-    VkInstance instance;
-    unique_ptr<INSTANCE_STATE> instance_state;
-
-
-    debug_report_data *report_data;
+struct instance_layer_data {
+    VkInstance instance = VK_NULL_HANDLE;
+    debug_report_data *report_data = nullptr;
     std::vector<VkDebugReportCallbackEXT> logging_callback;
-    VkLayerDispatchTable *device_dispatch_table;
-    VkLayerInstanceDispatchTable *instance_dispatch_table;
+    VkLayerInstanceDispatchTable dispatch_table;
 
-    devExts device_extensions;
+    CALL_STATE vkEnumeratePhysicalDevicesState = UNCALLED;
+    uint32_t physical_devices_count = 0;
+    CHECK_DISABLED disabled = {};
+
+    unordered_map<VkPhysicalDevice, PHYSICAL_DEVICE_STATE> physical_device_map;
+    unordered_map<VkSurfaceKHR, SURFACE_STATE> surface_map;
+
+    bool surfaceExtensionEnabled = false;
+    bool displayExtensionEnabled = false;
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    bool androidSurfaceExtensionEnabled = false;
+#endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    bool mirSurfaceExtensionEnabled = false;
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    bool waylandSurfaceExtensionEnabled = false;
+#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    bool win32SurfaceExtensionEnabled = false;
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+    bool xcbSurfaceExtensionEnabled = false;
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+    bool xlibSurfaceExtensionEnabled = false;
+#endif
+};
+
+struct layer_data {
+    debug_report_data *report_data = nullptr;
+    VkLayerDispatchTable dispatch_table;
+
+    devExts device_extensions = {};
     unordered_set<VkQueue> queues;  // All queues under given device
-    // Vector indices correspond to queueFamilyIndex
-    vector<unique_ptr<VkQueueFamilyProperties>> queue_family_properties;
     // Global set of all cmdBuffers that are inFlight on this device
     unordered_set<VkCommandBuffer> globalInFlightCmdBuffers;
     // Layer specific data
-    unordered_map<VkSampler, unique_ptr<SAMPLER_NODE>> samplerMap;
-    unordered_map<VkImageView, unique_ptr<VkImageViewCreateInfo>> imageViewMap;
-    unordered_map<VkImage, unique_ptr<IMAGE_NODE>> imageMap;
-    unordered_map<VkBufferView, unique_ptr<VkBufferViewCreateInfo>> bufferViewMap;
+    unordered_map<VkSampler, unique_ptr<SAMPLER_STATE>> samplerMap;
+    unordered_map<VkImageView, unique_ptr<IMAGE_VIEW_STATE>> imageViewMap;
+    unordered_map<VkImage, unique_ptr<IMAGE_STATE>> imageMap;
+    unordered_map<VkBufferView, unique_ptr<BUFFER_VIEW_STATE>> bufferViewMap;
     unordered_map<VkBuffer, unique_ptr<BUFFER_NODE>> bufferMap;
-    unordered_map<VkPipeline, PIPELINE_NODE *> pipelineMap;
+    unordered_map<VkPipeline, PIPELINE_STATE *> pipelineMap;
     unordered_map<VkCommandPool, COMMAND_POOL_NODE> commandPoolMap;
-    unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> descriptorPoolMap;
+    unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_STATE *> descriptorPoolMap;
     unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> setMap;
     unordered_map<VkDescriptorSetLayout, cvdescriptorset::DescriptorSetLayout *> descriptorSetLayoutMap;
     unordered_map<VkPipelineLayout, PIPELINE_LAYOUT_NODE> pipelineLayoutMap;
     unordered_map<VkDeviceMemory, unique_ptr<DEVICE_MEM_INFO>> memObjMap;
     unordered_map<VkFence, FENCE_NODE> fenceMap;
     unordered_map<VkQueue, QUEUE_NODE> queueMap;
-    unordered_map<VkEvent, EVENT_NODE> eventMap;
+    unordered_map<VkEvent, EVENT_STATE> eventMap;
     unordered_map<QueryObject, bool> queryToStateMap;
     unordered_map<VkQueryPool, QUERY_POOL_NODE> queryPoolMap;
     unordered_map<VkSemaphore, SEMAPHORE_NODE> semaphoreMap;
     unordered_map<VkCommandBuffer, GLOBAL_CB_NODE *> commandBufferMap;
-    unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_NODE>> frameBufferMap;
+    unordered_map<VkFramebuffer, unique_ptr<FRAMEBUFFER_STATE>> frameBufferMap;
     unordered_map<VkImage, vector<ImageSubresourcePair>> imageSubresourceMap;
     unordered_map<ImageSubresourcePair, IMAGE_LAYOUT_NODE> imageLayoutMap;
-    unordered_map<VkRenderPass, RENDER_PASS_NODE *> renderPassMap;
+    unordered_map<VkRenderPass, unique_ptr<RENDER_PASS_STATE>> renderPassMap;
     unordered_map<VkShaderModule, unique_ptr<shader_module>> shaderModuleMap;
-    VkDevice device;
+    VkDevice device = VK_NULL_HANDLE;
 
+    instance_layer_data *instance_data = nullptr;  // from device to enclosing instance
+
+    VkPhysicalDeviceFeatures enabled_features = {};
     // Device specific data
-    PHYS_DEV_PROPERTIES_NODE phys_dev_properties;
-    VkPhysicalDeviceMemoryProperties phys_dev_mem_props;
-    VkPhysicalDeviceFeatures physical_device_features;
-    unique_ptr<PHYSICAL_DEVICE_STATE> physical_device_state;
-
-    layer_data()
-        : instance_state(nullptr), report_data(nullptr), device_dispatch_table(nullptr), instance_dispatch_table(nullptr),
-          device_extensions(), device(VK_NULL_HANDLE), phys_dev_properties{}, phys_dev_mem_props{}, physical_device_features{},
-          physical_device_state(nullptr){};
+    PHYS_DEV_PROPERTIES_NODE phys_dev_properties = {};
+    VkPhysicalDeviceMemoryProperties phys_dev_mem_props = {};
 };
 
 // TODO : Do we need to guard access to layer_data_map w/ lock?
 static unordered_map<void *, layer_data *> layer_data_map;
+static unordered_map<void *, instance_layer_data *> instance_layer_data_map;
 
 static const VkLayerProperties global_layer = {
     "VK_LAYER_LUNARG_core_validation", VK_LAYER_API_VERSION, 1, "LunarG Validation Layer",
@@ -253,8 +275,8 @@
 // TODO : This can be much smarter, using separate locks for separate global data
 static std::mutex global_lock;
 
-// Return ImageViewCreateInfo ptr for specified imageView or else NULL
-VkImageViewCreateInfo *getImageViewData(const layer_data *dev_data, VkImageView image_view) {
+// Return IMAGE_VIEW_STATE ptr for specified imageView or else NULL
+IMAGE_VIEW_STATE *getImageViewState(const layer_data *dev_data, VkImageView image_view) {
     auto iv_it = dev_data->imageViewMap.find(image_view);
     if (iv_it == dev_data->imageViewMap.end()) {
         return nullptr;
@@ -262,7 +284,7 @@
     return iv_it->second.get();
 }
 // Return sampler node ptr for specified sampler or else NULL
-SAMPLER_NODE *getSamplerNode(const layer_data *dev_data, VkSampler sampler) {
+SAMPLER_STATE *getSamplerState(const layer_data *dev_data, VkSampler sampler) {
     auto sampler_it = dev_data->samplerMap.find(sampler);
     if (sampler_it == dev_data->samplerMap.end()) {
         return nullptr;
@@ -270,7 +292,7 @@
     return sampler_it->second.get();
 }
 // Return image node ptr for specified image or else NULL
-IMAGE_NODE *getImageNode(const layer_data *dev_data, VkImage image) {
+IMAGE_STATE *getImageState(const layer_data *dev_data, VkImage image) {
     auto img_it = dev_data->imageMap.find(image);
     if (img_it == dev_data->imageMap.end()) {
         return nullptr;
@@ -302,7 +324,7 @@
     return img_it->second;
 }
 // Return buffer node ptr for specified buffer or else NULL
-VkBufferViewCreateInfo *getBufferViewInfo(const layer_data *my_data, VkBufferView buffer_view) {
+BUFFER_VIEW_STATE *getBufferViewState(const layer_data *my_data, VkBufferView buffer_view) {
     auto bv_it = my_data->bufferViewMap.find(buffer_view);
     if (bv_it == my_data->bufferViewMap.end()) {
         return nullptr;
@@ -318,7 +340,7 @@
     return &it->second;
 }
 
-EVENT_NODE *getEventNode(layer_data *dev_data, VkEvent event) {
+EVENT_STATE *getEventNode(layer_data *dev_data, VkEvent event) {
     auto it = dev_data->eventMap.find(event);
     if (it == dev_data->eventMap.end()) {
         return nullptr;
@@ -358,26 +380,34 @@
     return &it->second;
 }
 
-static VkDeviceMemory *get_object_mem_binding(layer_data *my_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
+PHYSICAL_DEVICE_STATE *getPhysicalDeviceState(instance_layer_data *instance_data, VkPhysicalDevice phys) {
+    auto it = instance_data->physical_device_map.find(phys);
+    if (it == instance_data->physical_device_map.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+SURFACE_STATE *getSurfaceState(instance_layer_data *instance_data, VkSurfaceKHR surface) {
+    auto it = instance_data->surface_map.find(surface);
+    if (it == instance_data->surface_map.end()) {
+        return nullptr;
+    }
+    return &it->second;
+}
+
+// Return ptr to memory binding for given handle of specified type
+static BINDABLE *GetObjectMemBinding(layer_data *my_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
     switch (type) {
-    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
-        auto img_node = getImageNode(my_data, VkImage(handle));
-        if (img_node)
-            return &img_node->mem;
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
-        auto buff_node = getBufferNode(my_data, VkBuffer(handle));
-        if (buff_node)
-            return &buff_node->mem;
-        break;
-    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
+        return getImageState(my_data, VkImage(handle));
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
+        return getBufferNode(my_data, VkBuffer(handle));
     default:
         break;
     }
     return nullptr;
 }
-
 // prototype
 static GLOBAL_CB_NODE *getCBNode(layer_data const *, const VkCommandBuffer);
 
@@ -406,10 +436,10 @@
 // Helper function to validate usage flags for buffers
 // For given buffer_node send actual vs. desired usage off to helper above where
 //  an error will be flagged if usage is not correct
-static bool ValidateImageUsageFlags(layer_data *dev_data, IMAGE_NODE const *image_node, VkFlags desired, VkBool32 strict,
+static bool ValidateImageUsageFlags(layer_data *dev_data, IMAGE_STATE const *image_state, VkFlags desired, VkBool32 strict,
                                     char const *func_name, char const *usage_string) {
-    return validate_usage_flags(dev_data, image_node->createInfo.usage, desired, strict,
-                                reinterpret_cast<const uint64_t &>(image_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+    return validate_usage_flags(dev_data, image_state->createInfo.usage, desired, strict,
+                                reinterpret_cast<const uint64_t &>(image_state->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
                                 "image", func_name, usage_string);
 }
 
@@ -448,6 +478,10 @@
         return "image";
     case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
         return "buffer";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT:
+        return "image view";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT:
+        return "buffer view";
     case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
         return "swapchain";
     case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT:
@@ -458,10 +492,18 @@
         return "event";
     case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT:
         return "query pool";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT:
+        return "descriptor pool";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT:
+        return "command pool";
     case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT:
         return "pipeline";
     case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT:
         return "sampler";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT:
+        return "renderpass";
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT:
+        return "device memory";
     case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT:
         return "semaphore";
     default:
@@ -475,7 +517,7 @@
     DEVICE_MEM_INFO *mem_info = getMemObjInfo(dev_data, mem);
     if (mem_info) {
         if (!mem_info->bound_ranges[bound_object_handle].valid) {
-            return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+            return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                            reinterpret_cast<uint64_t &>(mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM",
                            "%s: Cannot read invalid region of memory allocation 0x%" PRIx64 " for bound %s object 0x%" PRIx64
                            ", please fill the memory before using.",
@@ -484,26 +526,26 @@
     }
     return false;
 }
-// For given image_node
-//  If mem is special swapchain key, then verify that image_node valid member is true
+// For given image_state
+//  If mem is special swapchain key, then verify that image_state valid member is true
 //  Else verify that the image's bound memory range is valid
-static bool ValidateImageMemoryIsValid(layer_data *dev_data, IMAGE_NODE *image_node, const char *functionName) {
-    if (image_node->mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
-        if (!image_node->valid) {
-            return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                           reinterpret_cast<uint64_t &>(image_node->mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM",
+static bool ValidateImageMemoryIsValid(layer_data *dev_data, IMAGE_STATE *image_state, const char *functionName) {
+    if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
+        if (!image_state->valid) {
+            return log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                           reinterpret_cast<uint64_t &>(image_state->binding.mem), __LINE__, MEMTRACK_INVALID_MEM_REGION, "MEM",
                            "%s: Cannot read invalid swapchain image 0x%" PRIx64 ", please fill the memory before using.",
-                           functionName, reinterpret_cast<uint64_t &>(image_node->image));
+                           functionName, reinterpret_cast<uint64_t &>(image_state->image));
         }
     } else {
-        return ValidateMemoryIsValid(dev_data, image_node->mem, reinterpret_cast<uint64_t &>(image_node->image),
+        return ValidateMemoryIsValid(dev_data, image_state->binding.mem, reinterpret_cast<uint64_t &>(image_state->image),
                                      VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, functionName);
     }
     return false;
 }
 // For given buffer_node, verify that the range it's bound to is valid
 static bool ValidateBufferMemoryIsValid(layer_data *dev_data, BUFFER_NODE *buffer_node, const char *functionName) {
-    return ValidateMemoryIsValid(dev_data, buffer_node->mem, reinterpret_cast<uint64_t &>(buffer_node->buffer),
+    return ValidateMemoryIsValid(dev_data, buffer_node->binding.mem, reinterpret_cast<uint64_t &>(buffer_node->buffer),
                                  VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, functionName);
 }
 // For the given memory allocation, set the range bound by the given handle object to the valid param value
@@ -514,18 +556,18 @@
     }
 }
 // For given image node
-//  If mem is special swapchain key, then set entire image_node to valid param value
+//  If mem is special swapchain key, then set entire image_state to valid param value
 //  Else set the image's bound memory range to valid param value
-static void SetImageMemoryValid(layer_data *dev_data, IMAGE_NODE *image_node, bool valid) {
-    if (image_node->mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
-        image_node->valid = valid;
+static void SetImageMemoryValid(layer_data *dev_data, IMAGE_STATE *image_state, bool valid) {
+    if (image_state->binding.mem == MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
+        image_state->valid = valid;
     } else {
-        SetMemoryValid(dev_data, image_node->mem, reinterpret_cast<uint64_t &>(image_node->image), valid);
+        SetMemoryValid(dev_data, image_state->binding.mem, reinterpret_cast<uint64_t &>(image_state->image), valid);
     }
 }
 // For given buffer node set the buffer's bound memory range to valid param value
 static void SetBufferMemoryValid(layer_data *dev_data, BUFFER_NODE *buffer_node, bool valid) {
-    SetMemoryValid(dev_data, buffer_node->mem, reinterpret_cast<uint64_t &>(buffer_node->buffer), valid);
+    SetMemoryValid(dev_data, buffer_node->binding.mem, reinterpret_cast<uint64_t &>(buffer_node->buffer), valid);
 }
 // Find CB Info and add mem reference to list container
 // Find Mem Obj Info and add CB reference to list container
@@ -539,12 +581,12 @@
         // First update CB binding in MemObj mini CB list
         DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, mem);
         if (pMemInfo) {
-            pMemInfo->command_buffer_bindings.insert(cb);
             // Now update CBInfo's Mem reference list
-            GLOBAL_CB_NODE *pCBNode = getCBNode(dev_data, cb);
+            GLOBAL_CB_NODE *cb_node = getCBNode(dev_data, cb);
+            pMemInfo->cb_bindings.insert(cb_node);
             // TODO: keep track of all destroyed CBs so we know if this is a stale or simply invalid object
-            if (pCBNode) {
-                pCBNode->memObjs.insert(mem);
+            if (cb_node) {
+                cb_node->memObjs.insert(mem);
             }
         }
     }
@@ -552,55 +594,82 @@
 }
 
 // Create binding link between given sampler and command buffer node
-void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *cb_node, SAMPLER_NODE *sampler_node) {
-    sampler_node->cb_bindings.insert(cb_node);
-    cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(sampler_node->sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT});
+void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *cb_node, SAMPLER_STATE *sampler_state) {
+    sampler_state->cb_bindings.insert(cb_node);
+    cb_node->object_bindings.insert(
+        {reinterpret_cast<uint64_t &>(sampler_state->sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT});
 }
 
 // Create binding link between given image node and command buffer node
-void AddCommandBufferBindingImage(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_NODE *img_node) {
+void AddCommandBufferBindingImage(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_STATE *image_state) {
     // Skip validation if this image was created through WSI
-    if (img_node->mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
+    if (image_state->binding.mem != MEMTRACKER_SWAP_CHAIN_IMAGE_KEY) {
         // First update CB binding in MemObj mini CB list
-        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, img_node->mem);
+        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, image_state->binding.mem);
         if (pMemInfo) {
-            pMemInfo->command_buffer_bindings.insert(cb_node->commandBuffer);
+            pMemInfo->cb_bindings.insert(cb_node);
             // Now update CBInfo's Mem reference list
-            cb_node->memObjs.insert(img_node->mem);
+            cb_node->memObjs.insert(image_state->binding.mem);
         }
-        cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(img_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
+        // Now update cb binding for image
+        cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(image_state->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
+        image_state->cb_bindings.insert(cb_node);
     }
-    // Now update cb binding for image
-    img_node->cb_bindings.insert(cb_node);
+}
+
+// Create binding link between given image view node and its image with command buffer node
+void AddCommandBufferBindingImageView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, IMAGE_VIEW_STATE *view_state) {
+    // First add bindings for imageView
+    view_state->cb_bindings.insert(cb_node);
+    cb_node->object_bindings.insert(
+        {reinterpret_cast<uint64_t &>(view_state->image_view), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT});
+    auto image_state = getImageState(dev_data, view_state->create_info.image);
+    // Add bindings for image within imageView
+    if (image_state) {
+        AddCommandBufferBindingImage(dev_data, cb_node, image_state);
+    }
 }
 
 // Create binding link between given buffer node and command buffer node
 void AddCommandBufferBindingBuffer(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_NODE *buff_node) {
     // First update CB binding in MemObj mini CB list
-    DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, buff_node->mem);
+    DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, buff_node->binding.mem);
     if (pMemInfo) {
-        pMemInfo->command_buffer_bindings.insert(cb_node->commandBuffer);
+        pMemInfo->cb_bindings.insert(cb_node);
         // Now update CBInfo's Mem reference list
-        cb_node->memObjs.insert(buff_node->mem);
-        cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
+        cb_node->memObjs.insert(buff_node->binding.mem);
     }
     // Now update cb binding for buffer
+    cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
     buff_node->cb_bindings.insert(cb_node);
 }
 
+// Create binding link between given buffer view node and its buffer with command buffer node
+void AddCommandBufferBindingBufferView(const layer_data *dev_data, GLOBAL_CB_NODE *cb_node, BUFFER_VIEW_STATE *view_state) {
+    // First add bindings for bufferView
+    view_state->cb_bindings.insert(cb_node);
+    cb_node->object_bindings.insert(
+        {reinterpret_cast<uint64_t &>(view_state->buffer_view), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT});
+    auto buffer_node = getBufferNode(dev_data, view_state->create_info.buffer);
+    // Add bindings for buffer within bufferView
+    if (buffer_node) {
+        AddCommandBufferBindingBuffer(dev_data, cb_node, buffer_node);
+    }
+}
+
 // For every mem obj bound to particular CB, free bindings related to that CB
-static void clear_cmd_buf_and_mem_references(layer_data *dev_data, GLOBAL_CB_NODE *pCBNode) {
-    if (pCBNode) {
-        if (pCBNode->memObjs.size() > 0) {
-            for (auto mem : pCBNode->memObjs) {
+static void clear_cmd_buf_and_mem_references(layer_data *dev_data, GLOBAL_CB_NODE *cb_node) {
+    if (cb_node) {
+        if (cb_node->memObjs.size() > 0) {
+            for (auto mem : cb_node->memObjs) {
                 DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
                 if (pInfo) {
-                    pInfo->command_buffer_bindings.erase(pCBNode->commandBuffer);
+                    pInfo->cb_bindings.erase(cb_node);
                 }
             }
-            pCBNode->memObjs.clear();
+            cb_node->memObjs.clear();
         }
-        pCBNode->validate_functions.clear();
+        cb_node->validate_functions.clear();
     }
 }
 // Overloaded call to above function when GLOBAL_CB_NODE has not already been looked-up
@@ -608,118 +677,63 @@
     clear_cmd_buf_and_mem_references(dev_data, getCBNode(dev_data, cb));
 }
 
-// For given MemObjInfo, report Obj & CB bindings
-static bool reportMemReferencesAndCleanUp(layer_data *dev_data, DEVICE_MEM_INFO *pMemObjInfo) {
-    bool skip_call = false;
-    size_t cmdBufRefCount = pMemObjInfo->command_buffer_bindings.size();
-    size_t objRefCount = pMemObjInfo->obj_bindings.size();
-
-    if ((pMemObjInfo->command_buffer_bindings.size()) != 0) {
-        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                            (uint64_t)pMemObjInfo->mem, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
-                            "Attempting to free memory object 0x%" PRIxLEAST64 " which still contains " PRINTF_SIZE_T_SPECIFIER
-                            " references",
-                            (uint64_t)pMemObjInfo->mem, (cmdBufRefCount + objRefCount));
+// Clear a single object binding from given memory object, or report error if binding is missing
+static bool ClearMemoryObjectBinding(layer_data *dev_data, uint64_t handle, VkDebugReportObjectTypeEXT type, VkDeviceMemory mem) {
+    DEVICE_MEM_INFO *mem_info = getMemObjInfo(dev_data, mem);
+    // This obj is bound to a memory object. Remove the reference to this object in that memory object's list
+    if (mem_info && !mem_info->obj_bindings.erase({handle, type})) {
+        return log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT,
+                    "MEM", "While trying to clear mem binding for %s obj 0x%" PRIxLEAST64
+                           ", unable to find that object referenced by mem obj 0x%" PRIxLEAST64,
+                    object_type_to_string(type), handle, (uint64_t)mem);
     }
-
-    if (cmdBufRefCount > 0 && pMemObjInfo->command_buffer_bindings.size() > 0) {
-        for (auto cb : pMemObjInfo->command_buffer_bindings) {
-            log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                    (uint64_t)cb, __LINE__, MEMTRACK_FREED_MEM_REF, "MEM",
-                    "Command Buffer 0x%p still has a reference to mem obj 0x%" PRIxLEAST64, cb, (uint64_t)pMemObjInfo->mem);
-        }
-        // Clear the list of hanging references
-        pMemObjInfo->command_buffer_bindings.clear();
-    }
-
-    if (objRefCount > 0 && pMemObjInfo->obj_bindings.size() > 0) {
-        for (auto obj : pMemObjInfo->obj_bindings) {
-            log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, obj.type, obj.handle, __LINE__,
-                    MEMTRACK_FREED_MEM_REF, "MEM", "VK Object 0x%" PRIxLEAST64 " still has a reference to mem obj 0x%" PRIxLEAST64,
-                    obj.handle, (uint64_t)pMemObjInfo->mem);
-        }
-        // Clear the list of hanging references
-        pMemObjInfo->obj_bindings.clear();
-    }
-    return skip_call;
+    return false;
 }
 
-static bool freeMemObjInfo(layer_data *dev_data, void *object, VkDeviceMemory mem, bool internal) {
-    bool skip_call = false;
-    // Parse global list to find info w/ mem
-    DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
-    if (pInfo) {
-        // TODO: Verify against Valid Use section
-        // Clear any CB bindings for completed CBs
-        //   TODO : Is there a better place to do this?
-
-        assert(pInfo->object != VK_NULL_HANDLE);
-        // clear_cmd_buf_and_mem_references removes elements from
-        // pInfo->command_buffer_bindings -- this copy not needed in c++14,
-        // and probably not needed in practice in c++11
-        auto bindings = pInfo->command_buffer_bindings;
-        for (auto cb : bindings) {
-            if (!dev_data->globalInFlightCmdBuffers.count(cb)) {
-                clear_cmd_buf_and_mem_references(dev_data, cb);
-            }
-        }
-
-        // Now verify that no references to this mem obj remain and remove bindings
-        if (pInfo->command_buffer_bindings.size() || pInfo->obj_bindings.size()) {
-            skip_call |= reportMemReferencesAndCleanUp(dev_data, pInfo);
-        }
-        // Delete mem obj info
-        dev_data->memObjMap.erase(dev_data->memObjMap.find(mem));
-    } else if (VK_NULL_HANDLE != mem) {
-        // The request is to free an invalid, non-zero handle
-        skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                            VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                            reinterpret_cast<uint64_t &>(mem), __LINE__,
-                            MEMTRACK_INVALID_MEM_OBJ,
-                            "MEM", "Request to delete memory object 0x%"
-                            PRIxLEAST64 " not present in memory Object Map",
-                            reinterpret_cast<uint64_t &>(mem));
-    }
-    return skip_call;
-}
-
-// Remove object binding performs 3 tasks:
-// 1. Remove ObjectInfo from MemObjInfo list container of obj bindings & free it
-// 2. Clear mem binding for image/buffer by setting its handle to 0
-// TODO : This only applied to Buffer, Image, and Swapchain objects now, how should it be updated/customized?
-static bool clear_object_binding(layer_data *dev_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
-    // TODO : Need to customize images/buffers/swapchains to track mem binding and clear it here appropriately
-    bool skip_call = false;
-    VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
-    if (pMemBinding) {
-        DEVICE_MEM_INFO *pMemObjInfo = getMemObjInfo(dev_data, *pMemBinding);
-        // TODO : Make sure this is a reasonable way to reset mem binding
-        *pMemBinding = VK_NULL_HANDLE;
-        if (pMemObjInfo) {
-            // This obj is bound to a memory object. Remove the reference to this object in that memory object's list,
-            // and set the objects memory binding pointer to NULL.
-            if (!pMemObjInfo->obj_bindings.erase({handle, type})) {
-                skip_call |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_OBJECT,
-                            "MEM", "While trying to clear mem binding for %s obj 0x%" PRIxLEAST64
-                                   ", unable to find that object referenced by mem obj 0x%" PRIxLEAST64,
-                            object_type_to_string(type), handle, (uint64_t)pMemObjInfo->mem);
+// ClearMemoryObjectBindings clears the binding of objects to memory
+//  For the given object it pulls the memory bindings and makes sure that the bindings
+//  no longer refer to the object being cleared. This occurs when objects are destroyed.
+static bool ClearMemoryObjectBindings(layer_data *dev_data, uint64_t handle, VkDebugReportObjectTypeEXT type) {
+    bool skip = false;
+    BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type);
+    if (mem_binding) {
+        if (!mem_binding->sparse) {
+            skip = ClearMemoryObjectBinding(dev_data, handle, type, mem_binding->binding.mem);
+        } else { // Sparse, clear all bindings
+            for (auto& sparse_mem_binding : mem_binding->sparse_bindings) {
+                skip |= ClearMemoryObjectBinding(dev_data, handle, type, sparse_mem_binding.mem);
             }
         }
     }
-    return skip_call;
+    return skip;
+}
+
+// For given mem object, verify that it is not null or UNBOUND, if it is, report error. Return skip value.
+bool VerifyBoundMemoryIsValid(const layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, const char *api_name,
+                              const char *type_name) {
+    bool result = false;
+    if (VK_NULL_HANDLE == mem) {
+        result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle,
+                         __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
+                         "%s: Vk%s object 0x%" PRIxLEAST64 " used with no memory bound. Memory should be bound by calling "
+                         "vkBind%sMemory().",
+                         api_name, type_name, handle, type_name);
+    } else if (MEMORY_UNBOUND == mem) {
+        result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, handle,
+                         __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
+                         "%s: Vk%s object 0x%" PRIxLEAST64 " used with no memory bound and previously bound memory was freed. "
+                         "Memory must not be freed prior to this operation.",
+                         api_name, type_name, handle);
+    }
+    return result;
 }
 
 // Check to see if memory was ever bound to this image
-bool ValidateMemoryIsBoundToImage(const layer_data *dev_data, const IMAGE_NODE *image_node, const char *api_name) {
+bool ValidateMemoryIsBoundToImage(const layer_data *dev_data, const IMAGE_STATE *image_state, const char *api_name) {
     bool result = false;
-    if (0 == (static_cast<uint32_t>(image_node->createInfo.flags) & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
-        if (0 == image_node->mem) {
-            result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
-                             reinterpret_cast<const uint64_t &>(image_node->image), __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
-                             "%s: VkImage object 0x%" PRIxLEAST64 " used without first calling vkBindImageMemory.", api_name,
-                             reinterpret_cast<const uint64_t &>(image_node->image));
-        }
+    if (0 == (static_cast<uint32_t>(image_state->createInfo.flags) & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
+        result = VerifyBoundMemoryIsValid(dev_data, image_state->binding.mem, reinterpret_cast<const uint64_t &>(image_state->image),
+                                          api_name, "Image");
     }
     return result;
 }
@@ -728,55 +742,64 @@
 bool ValidateMemoryIsBoundToBuffer(const layer_data *dev_data, const BUFFER_NODE *buffer_node, const char *api_name) {
     bool result = false;
     if (0 == (static_cast<uint32_t>(buffer_node->createInfo.flags) & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)) {
-        if (0 == buffer_node->mem) {
-            result = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
-                             reinterpret_cast<const uint64_t &>(buffer_node->buffer), __LINE__, MEMTRACK_OBJECT_NOT_BOUND, "MEM",
-                             "%s: VkBuffer object 0x%" PRIxLEAST64 " used without first calling vkBindBufferMemory.", api_name,
-                             reinterpret_cast<const uint64_t &>(buffer_node->buffer));
-        }
+        result = VerifyBoundMemoryIsValid(dev_data, buffer_node->binding.mem,
+                                          reinterpret_cast<const uint64_t &>(buffer_node->buffer), api_name, "Buffer");
     }
     return result;
 }
 
+// SetMemBinding is used to establish immutable, non-sparse binding between a single image/buffer object and memory object
 // For NULL mem case, output warning
 // Make sure given object is in global object map
 //  IF a previous binding existed, output validation error
 //  Otherwise, add reference from objectInfo to memoryInfo
 //  Add reference off of objInfo
-static bool set_mem_binding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle,
-                                VkDebugReportObjectTypeEXT type, const char *apiName) {
+static bool SetMemBinding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle, VkDebugReportObjectTypeEXT type,
+                          const char *apiName) {
     bool skip_call = false;
-    // Handle NULL case separately, just clear previous binding & decrement reference
+    // It's an error to bind an object to NULL memory
     if (mem == VK_NULL_HANDLE) {
-        // TODO: Verify against Valid Use section of spec.
         skip_call = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, type, handle, __LINE__, MEMTRACK_INVALID_MEM_OBJ,
                             "MEM", "In %s, attempting to Bind Obj(0x%" PRIxLEAST64 ") to NULL", apiName, handle);
     } else {
-        VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
-        assert(pMemBinding);
-        DEVICE_MEM_INFO *pMemInfo = getMemObjInfo(dev_data, mem);
-        if (pMemInfo) {
-            DEVICE_MEM_INFO *pPrevBinding = getMemObjInfo(dev_data, *pMemBinding);
-            if (pPrevBinding != NULL) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)mem, __LINE__, MEMTRACK_REBIND_OBJECT,
-                                     "MEM", "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64
-                                            ") which has already been bound to mem object 0x%" PRIxLEAST64,
-                                     apiName, (uint64_t)mem, handle, (uint64_t)pPrevBinding->mem);
+        BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type);
+        assert(mem_binding);
+        // TODO : Add check here to make sure object isn't sparse
+        //  VALIDATION_ERROR_00792 for buffers
+        //  VALIDATION_ERROR_00804 for images
+        assert(!mem_binding->sparse);
+        DEVICE_MEM_INFO *mem_info = getMemObjInfo(dev_data, mem);
+        if (mem_info) {
+            DEVICE_MEM_INFO *prev_binding = getMemObjInfo(dev_data, mem_binding->binding.mem);
+            if (prev_binding) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            reinterpret_cast<uint64_t &>(mem), __LINE__, MEMTRACK_REBIND_OBJECT, "MEM",
+                            "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64
+                            ") which has already been bound to mem object 0x%" PRIxLEAST64,
+                            apiName, reinterpret_cast<uint64_t &>(mem), handle, reinterpret_cast<uint64_t &>(prev_binding->mem));
+            } else if (mem_binding->binding.mem == MEMORY_UNBOUND) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            reinterpret_cast<uint64_t &>(mem), __LINE__, MEMTRACK_REBIND_OBJECT, "MEM",
+                            "In %s, attempting to bind memory (0x%" PRIxLEAST64 ") to object (0x%" PRIxLEAST64
+                            ") which was previous bound to memory that has since been freed. Memory bindings are immutable in "
+                            "Vulkan so this attempt to bind to new memory is not allowed.",
+                            apiName, reinterpret_cast<uint64_t &>(mem), handle);
             } else {
-                pMemInfo->obj_bindings.insert({handle, type});
+                mem_info->obj_bindings.insert({handle, type});
                 // For image objects, make sure default memory state is correctly set
                 // TODO : What's the best/correct way to handle this?
                 if (VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT == type) {
-                    auto const image_node = getImageNode(dev_data, VkImage(handle));
-                    if (image_node) {
-                        VkImageCreateInfo ici = image_node->createInfo;
+                    auto const image_state = getImageState(dev_data, VkImage(handle));
+                    if (image_state) {
+                        VkImageCreateInfo ici = image_state->createInfo;
                         if (ici.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
                             // TODO::  More memory state transition stuff.
                         }
                     }
                 }
-                *pMemBinding = mem;
+                mem_binding->binding.mem = mem;
             }
         }
     }
@@ -789,20 +812,21 @@
 //  Add reference from objectInfo to memoryInfo
 //  Add reference off of object's binding info
 // Return VK_TRUE if addition is successful, VK_FALSE otherwise
-static bool set_sparse_mem_binding(layer_data *dev_data, VkDeviceMemory mem, uint64_t handle,
-                                       VkDebugReportObjectTypeEXT type, const char *apiName) {
+static bool SetSparseMemBinding(layer_data *dev_data, MEM_BINDING binding, uint64_t handle, VkDebugReportObjectTypeEXT type,
+                                const char *apiName) {
     bool skip_call = VK_FALSE;
     // Handle NULL case separately, just clear previous binding & decrement reference
-    if (mem == VK_NULL_HANDLE) {
-        skip_call = clear_object_binding(dev_data, handle, type);
+    if (binding.mem == VK_NULL_HANDLE) {
+        // TODO : This should cause the range of the resource to be unbound according to spec
     } else {
-        VkDeviceMemory *pMemBinding = get_object_mem_binding(dev_data, handle, type);
-        assert(pMemBinding);
-        DEVICE_MEM_INFO *pInfo = getMemObjInfo(dev_data, mem);
-        if (pInfo) {
-            pInfo->obj_bindings.insert({handle, type});
+        BINDABLE *mem_binding = GetObjectMemBinding(dev_data, handle, type);
+        assert(mem_binding);
+        assert(mem_binding->sparse);
+        DEVICE_MEM_INFO *mem_info = getMemObjInfo(dev_data, binding.mem);
+        if (mem_info) {
+            mem_info->obj_bindings.insert({handle, type});
             // Need to set mem binding for this object
-            *pMemBinding = mem;
+            mem_binding->sparse_bindings.insert(binding);
         }
     }
     return skip_call;
@@ -814,10 +838,10 @@
     *mem = VK_NULL_HANDLE;
     switch (type) {
     case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
-        *mem = getImageNode(dev_data, VkImage(handle))->mem;
+        *mem = getImageState(dev_data, VkImage(handle))->binding.mem;
         break;
     case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
-        *mem = getBufferNode(dev_data, VkBuffer(handle))->mem;
+        *mem = getBufferNode(dev_data, VkBuffer(handle))->binding.mem;
         break;
     default:
         assert(0);
@@ -857,7 +881,7 @@
                 __LINE__, MEMTRACK_NONE, "MEM", "    Mem object: 0x%" PRIxLEAST64, (uint64_t)(mem_info->mem));
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                 __LINE__, MEMTRACK_NONE, "MEM", "    Ref Count: " PRINTF_SIZE_T_SPECIFIER,
-                mem_info->command_buffer_bindings.size() + mem_info->obj_bindings.size());
+                mem_info->cb_bindings.size() + mem_info->obj_bindings.size());
         if (0 != mem_info->alloc_info.allocationSize) {
             string pAllocInfoMsg = vk_print_vkmemoryallocateinfo(&mem_info->alloc_info, "MEM(INFO):         ");
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
@@ -880,11 +904,11 @@
         log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
                 __LINE__, MEMTRACK_NONE, "MEM",
                 "    VK Command Buffer (CB) binding list of size " PRINTF_SIZE_T_SPECIFIER " elements",
-                mem_info->command_buffer_bindings.size());
-        if (mem_info->command_buffer_bindings.size() > 0) {
-            for (auto cb : mem_info->command_buffer_bindings) {
+                mem_info->cb_bindings.size());
+        if (mem_info->cb_bindings.size() > 0) {
+            for (auto cb : mem_info->cb_bindings) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                        0, __LINE__, MEMTRACK_NONE, "MEM", "      VK CB 0x%p", cb);
+                        0, __LINE__, MEMTRACK_NONE, "MEM", "      VK command buffer 0x%p", cb);
             }
         }
     }
@@ -899,7 +923,7 @@
     }
 
     log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
-            MEMTRACK_NONE, "MEM", "Details of CB list (of size " PRINTF_SIZE_T_SPECIFIER " elements)",
+            MEMTRACK_NONE, "MEM", "Details of command buffer list (of size " PRINTF_SIZE_T_SPECIFIER " elements)",
             my_data->commandBufferMap.size());
     log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0, __LINE__,
             MEMTRACK_NONE, "MEM", "==================");
@@ -911,7 +935,8 @@
         pCBInfo = cb_node.second;
 
         log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, 0,
-                __LINE__, MEMTRACK_NONE, "MEM", "    CB Info (0x%p) has CB 0x%p", (void *)pCBInfo, (void *)pCBInfo->commandBuffer);
+                __LINE__, MEMTRACK_NONE, "MEM", "    CB Info (0x%p) has command buffer 0x%p", (void *)pCBInfo,
+                (void *)pCBInfo->commandBuffer);
 
         if (pCBInfo->memObjs.size() <= 0)
             continue;
@@ -1852,14 +1877,14 @@
         if (!a_at_end && (b_at_end || a_first < b_first)) {
             if (!used && log_msg(report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                         __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
-                        "Vertex attribute at location %d not consumed by VS", a_first)) {
+                        "Vertex attribute at location %d not consumed by vertex shader", a_first)) {
                 pass = false;
             }
             used = false;
             it_a++;
         } else if (!b_at_end && (a_at_end || b_first < a_first)) {
             if (log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, /*dev*/ 0,
-                        __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", "VS consumes input at location %d but not provided",
+                        __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", "Vertex shader consumes input at location %d but not provided",
                         b_first)) {
                 pass = false;
             }
@@ -1872,7 +1897,7 @@
             if (attrib_type != FORMAT_TYPE_UNDEFINED && input_type != FORMAT_TYPE_UNDEFINED && attrib_type != input_type) {
                 if (log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                             __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
-                            "Attribute type of `%s` at location %d does not match VS input type of `%s`",
+                            "Attribute type of `%s` at location %d does not match vertex shader input type of `%s`",
                             string_VkFormat(it_a->second->format), a_first,
                             describe_type(vs, it_b->second.type_id).c_str())) {
                     pass = false;
@@ -1920,13 +1945,14 @@
         if (!a_at_end && (b_at_end || it_a->first.first < it_b->first)) {
             if (log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                         __LINE__, SHADER_CHECKER_OUTPUT_NOT_CONSUMED, "SC",
-                        "FS writes to output location %d with no matching attachment", it_a->first.first)) {
+                        "fragment shader writes to output location %d with no matching attachment", it_a->first.first)) {
                 pass = false;
             }
             it_a++;
         } else if (!b_at_end && (a_at_end || it_a->first.first > it_b->first)) {
             if (log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
-                        __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", "Attachment %d not written by FS", it_b->first)) {
+                        __LINE__, SHADER_CHECKER_INPUT_NOT_PRODUCED, "SC", "Attachment %d not written by fragment shader",
+                        it_b->first)) {
                 pass = false;
             }
             it_b++;
@@ -1938,7 +1964,7 @@
             if (att_type != FORMAT_TYPE_UNDEFINED && output_type != FORMAT_TYPE_UNDEFINED && att_type != output_type) {
                 if (log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                             __LINE__, SHADER_CHECKER_INTERFACE_TYPE_MISMATCH, "SC",
-                            "Attachment %d of type `%s` does not match FS output type of `%s`", it_b->first,
+                            "Attachment %d of type `%s` does not match fragment shader output type of `%s`", it_b->first,
                             string_VkFormat(it_b->second),
                             describe_type(fs, it_a->second.type_id).c_str())) {
                     pass = false;
@@ -2181,13 +2207,14 @@
     if (!(pNode->status & status_mask)) {
         return log_msg(my_data->report_data, msg_flags, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                        reinterpret_cast<const uint64_t &>(pNode->commandBuffer), __LINE__, error_code, "DS",
-                       "CB object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<const uint64_t &>(pNode->commandBuffer), fail_msg);
+                       "command buffer object 0x%" PRIxLEAST64 ": %s", reinterpret_cast<const uint64_t &>(pNode->commandBuffer),
+                       fail_msg);
     }
     return false;
 }
 
 // Retrieve pipeline node ptr for given pipeline object
-static PIPELINE_NODE *getPipeline(layer_data const *my_data, VkPipeline pipeline) {
+static PIPELINE_STATE *getPipelineState(layer_data const *my_data, VkPipeline pipeline) {
     auto it = my_data->pipelineMap.find(pipeline);
     if (it == my_data->pipelineMap.end()) {
         return nullptr;
@@ -2195,15 +2222,15 @@
     return it->second;
 }
 
-static RENDER_PASS_NODE *getRenderPass(layer_data const *my_data, VkRenderPass renderpass) {
+static RENDER_PASS_STATE *getRenderPassState(layer_data const *my_data, VkRenderPass renderpass) {
     auto it = my_data->renderPassMap.find(renderpass);
     if (it == my_data->renderPassMap.end()) {
         return nullptr;
     }
-    return it->second;
+    return it->second.get();
 }
 
-static FRAMEBUFFER_NODE *getFramebuffer(const layer_data *my_data, VkFramebuffer framebuffer) {
+static FRAMEBUFFER_STATE *getFramebufferState(const layer_data *my_data, VkFramebuffer framebuffer) {
     auto it = my_data->frameBufferMap.find(framebuffer);
     if (it == my_data->frameBufferMap.end()) {
         return nullptr;
@@ -2228,7 +2255,7 @@
 }
 
 // Return true if for a given PSO, the given state enum is dynamic, else return false
-static bool isDynamic(const PIPELINE_NODE *pPipeline, const VkDynamicState state) {
+static bool isDynamic(const PIPELINE_STATE *pPipeline, const VkDynamicState state) {
     if (pPipeline && pPipeline->graphicsPipelineCI.pDynamicState) {
         for (uint32_t i = 0; i < pPipeline->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) {
             if (state == pPipeline->graphicsPipelineCI.pDynamicState->pDynamicStates[i])
@@ -2239,12 +2266,8 @@
 }
 
 // Validate state stored as flags at time of draw call
-static bool validate_draw_state_flags(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const PIPELINE_NODE *pPipe, bool indexedDraw) {
-    bool result;
-    result = validate_status(dev_data, pCB, CBSTATUS_VIEWPORT_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_VIEWPORT_NOT_BOUND,
-                             "Dynamic viewport state not set for this command buffer");
-    result |= validate_status(dev_data, pCB, CBSTATUS_SCISSOR_SET, VK_DEBUG_REPORT_ERROR_BIT_EXT, DRAWSTATE_SCISSOR_NOT_BOUND,
-                              "Dynamic scissor state not set for this command buffer");
+static bool validate_draw_state_flags(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe, bool indexedDraw) {
+    bool result = false;
     if (pPipe->graphicsPipelineCI.pInputAssemblyState &&
         ((pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST) ||
          (pPipe->graphicsPipelineCI.pInputAssemblyState->topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP))) {
@@ -2707,15 +2730,11 @@
     }
 }
 
-
-static bool validate_pipeline_shader_stage(debug_report_data *report_data,
-                                           VkPipelineShaderStageCreateInfo const *pStage,
-                                           PIPELINE_NODE *pipeline,
-                                           shader_module **out_module,
-                                           spirv_inst_iter *out_entrypoint,
-                                           VkPhysicalDeviceFeatures const *enabledFeatures,
-                                           std::unordered_map<VkShaderModule,
-                                           std::unique_ptr<shader_module>> const &shaderModuleMap) {
+static bool
+validate_pipeline_shader_stage(debug_report_data *report_data, VkPipelineShaderStageCreateInfo const *pStage,
+                               PIPELINE_STATE *pipeline, shader_module **out_module, spirv_inst_iter *out_entrypoint,
+                               VkPhysicalDeviceFeatures const *enabledFeatures,
+                               std::unordered_map<VkShaderModule, std::unique_ptr<shader_module>> const &shaderModuleMap) {
     bool pass = true;
     auto module_it = shaderModuleMap.find(pStage->module);
     auto module = *out_module = module_it->second.get();
@@ -2832,9 +2851,10 @@
 
 // Validate that the shaders used by the given pipeline and store the active_slots
 //  that are actually used by the pipeline into pPipeline->active_slots
-static bool validate_and_capture_pipeline_shader_state(debug_report_data *report_data, PIPELINE_NODE *pPipeline,
-                                                       VkPhysicalDeviceFeatures const *enabledFeatures,
-                                                       std::unordered_map<VkShaderModule, unique_ptr<shader_module>> const & shaderModuleMap) {
+static bool
+validate_and_capture_pipeline_shader_state(debug_report_data *report_data, PIPELINE_STATE *pPipeline,
+                                           VkPhysicalDeviceFeatures const *enabledFeatures,
+                                           std::unordered_map<VkShaderModule, unique_ptr<shader_module>> const &shaderModuleMap) {
     auto pCreateInfo = pPipeline->graphicsPipelineCI.ptr();
     int vertex_stage = get_shader_stage_id(VK_SHADER_STAGE_VERTEX_BIT);
     int fragment_stage = get_shader_stage_id(VK_SHADER_STAGE_FRAGMENT_BIT);
@@ -2895,8 +2915,9 @@
     return pass;
 }
 
-static bool validate_compute_pipeline(debug_report_data *report_data, PIPELINE_NODE *pPipeline, VkPhysicalDeviceFeatures const *enabledFeatures,
-                                      std::unordered_map<VkShaderModule, unique_ptr<shader_module>> const & shaderModuleMap) {
+static bool validate_compute_pipeline(debug_report_data *report_data, PIPELINE_STATE *pPipeline,
+                                      VkPhysicalDeviceFeatures const *enabledFeatures,
+                                      std::unordered_map<VkShaderModule, unique_ptr<shader_module>> const &shaderModuleMap) {
     auto pCreateInfo = pPipeline->computePipelineCI.ptr();
 
     shader_module *module;
@@ -2935,7 +2956,7 @@
             auto set = set_node->GetSet();
             result |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                               reinterpret_cast<const uint64_t &>(set), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
-                              "DS 0x%" PRIxLEAST64 " encountered the following validation error at %s() time: %s",
+                              "Descriptor set 0x%" PRIxLEAST64 " encountered the following validation error at %s() time: %s",
                               reinterpret_cast<const uint64_t &>(set), function, err_str.c_str());
         }
         set_node->GetStorageUpdates(std::get<1>(set_bindings_pair), &pCB->updateBuffers, &pCB->updateImages);
@@ -2944,7 +2965,7 @@
 }
 
 // For given pipeline, return number of MSAA samples, or one if MSAA disabled
-static VkSampleCountFlagBits getNumSamples(PIPELINE_NODE const *pipe) {
+static VkSampleCountFlagBits getNumSamples(PIPELINE_STATE const *pipe) {
     if (pipe->graphicsPipelineCI.pMultisampleState != NULL &&
         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO == pipe->graphicsPipelineCI.pMultisampleState->sType) {
         return pipe->graphicsPipelineCI.pMultisampleState->rasterizationSamples;
@@ -2965,13 +2986,11 @@
 }
 
 // Validate draw-time state related to the PSO
-static bool validatePipelineDrawtimeState(layer_data const *my_data,
-                                          LAST_BOUND_STATE const &state,
-                                          const GLOBAL_CB_NODE *pCB,
-                                          PIPELINE_NODE const *pPipeline) {
+static bool validatePipelineDrawtimeState(layer_data const *my_data, LAST_BOUND_STATE const &state, const GLOBAL_CB_NODE *pCB,
+                                          PIPELINE_STATE const *pPipeline) {
     bool skip_call = false;
 
-    // Verify Vtx binding
+    // Verify vertex binding
     if (pPipeline->vertexBindingDescriptions.size() > 0) {
         for (size_t i = 0; i < pPipeline->vertexBindingDescriptions.size(); i++) {
             auto vertex_binding = pPipeline->vertexBindingDescriptions[i].binding;
@@ -2983,7 +3002,7 @@
                     "The Pipeline State Object (0x%" PRIxLEAST64 ") expects that this Command Buffer's vertex binding Index %u "
                     "should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct "
                     "at index " PRINTF_SIZE_T_SPECIFIER " of pVertexBindingDescriptions has a binding value of %u.",
-                    (uint64_t)state.pipeline_node->pipeline, vertex_binding, i, vertex_binding);
+                    (uint64_t)state.pipeline_state->pipeline, vertex_binding, i, vertex_binding);
             }
         }
     } else {
@@ -2992,7 +3011,7 @@
                                  0, __LINE__, DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS, "DS",
                                  "Vertex buffers are bound to command buffer (0x%" PRIxLEAST64
                                  ") but no vertex buffers are attached to this Pipeline State Object (0x%" PRIxLEAST64 ").",
-                                 (uint64_t)pCB->commandBuffer, (uint64_t)state.pipeline_node->pipeline);
+                                 (uint64_t)pCB->commandBuffer, (uint64_t)state.pipeline_state->pipeline);
         }
     }
     // If Viewport or scissors are dynamic, verify that dynamic count matches PSO count.
@@ -3010,7 +3029,7 @@
                 std::stringstream ss;
                 ss << "Dynamic viewport(s) ";
                 list_bits(ss, missingViewportMask);
-                ss << " are used by PSO, but were not provided via calls to vkCmdSetViewport().";
+                ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetViewport().";
                 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                                      __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
                                      "%s", ss.str().c_str());
@@ -3024,7 +3043,7 @@
                 std::stringstream ss;
                 ss << "Dynamic scissor(s) ";
                 list_bits(ss, missingScissorMask);
-                ss << " are used by PSO, but were not provided via calls to vkCmdSetScissor().";
+                ss << " are used by pipeline state object, but were not provided via calls to vkCmdSetScissor().";
                 skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                                      __LINE__, DRAWSTATE_VIEWPORT_SCISSOR_MISMATCH, "DS",
                                      "%s", ss.str().c_str());
@@ -3038,7 +3057,7 @@
         (pPipeline->graphicsPipelineCI.pRasterizationState->rasterizerDiscardEnable == VK_FALSE)) {
         VkSampleCountFlagBits pso_num_samples = getNumSamples(pPipeline);
         if (pCB->activeRenderPass) {
-            const VkRenderPassCreateInfo *render_pass_info = pCB->activeRenderPass->pCreateInfo;
+            auto const render_pass_info = pCB->activeRenderPass->createInfo.ptr();
             const VkSubpassDescription *subpass_desc = &render_pass_info->pSubpasses[pCB->activeSubpass];
             uint32_t i;
 
@@ -3089,7 +3108,7 @@
     if (pCB->activeRenderPass) {
         std::string err_string;
         if ((pCB->activeRenderPass->renderPass != pPipeline->graphicsPipelineCI.renderPass) &&
-            !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->pCreateInfo, pPipeline->render_pass_ci.ptr(),
+            !verify_renderpass_compatibility(my_data, pCB->activeRenderPass->createInfo.ptr(), pPipeline->render_pass_ci.ptr(),
                                              err_string)) {
             // renderPass that PSO was created with must be compatible with active renderPass that PSO is being used with
             skip_call |=
@@ -3097,9 +3116,18 @@
                         reinterpret_cast<const uint64_t &>(pPipeline->pipeline), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
                         "At Draw time the active render pass (0x%" PRIxLEAST64 ") is incompatible w/ gfx pipeline "
                         "(0x%" PRIxLEAST64 ") that was created w/ render pass (0x%" PRIxLEAST64 ") due to: %s",
-                        reinterpret_cast<uint64_t &>(pCB->activeRenderPass->renderPass), reinterpret_cast<uint64_t &>(pPipeline),
+                        reinterpret_cast<uint64_t &>(pCB->activeRenderPass->renderPass),
+                        reinterpret_cast<uint64_t const &>(pPipeline->pipeline),
                         reinterpret_cast<const uint64_t &>(pPipeline->graphicsPipelineCI.renderPass), err_string.c_str());
         }
+
+        if (pPipeline->graphicsPipelineCI.subpass != pCB->activeSubpass) {
+            skip_call |=
+                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
+                        reinterpret_cast<uint64_t const &>(pPipeline->pipeline), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                        "Pipeline was built for subpass %u but used in subpass %u", pPipeline->graphicsPipelineCI.subpass,
+                        pCB->activeSubpass);
+        }
     }
     // TODO : Add more checks here
 
@@ -3111,7 +3139,7 @@
                                            const VkPipelineBindPoint bindPoint, const char *function) {
     bool result = false;
     auto const &state = cb_node->lastBound[bindPoint];
-    PIPELINE_NODE *pPipe = state.pipeline_node;
+    PIPELINE_STATE *pPipe = state.pipeline_state;
     if (nullptr == pPipe) {
         result |= log_msg(
             my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
@@ -3172,7 +3200,7 @@
                             result |= log_msg(
                                 my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                 (uint64_t)pSet->GetSet(), __LINE__, DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
-                                "DS 0x%" PRIxLEAST64 " bound but it was never updated. It is now being used to draw so "
+                                "Descriptor Set 0x%" PRIxLEAST64 " bound but was never updated. It is now being used to draw so "
                                 "this will result in undefined behavior.",
                                 (uint64_t)pSet->GetSet());
                         }
@@ -3196,7 +3224,7 @@
     bool skip_call = false;
 
     // First check to see if the physical device supports wide lines.
-    if ((VK_FALSE == my_data->phys_dev_properties.features.wideLines) && (1.0f != lineWidth)) {
+    if ((VK_FALSE == my_data->enabled_features.wideLines) && (1.0f != lineWidth)) {
         skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, target, __LINE__,
                              dsError, "DS", "Attempt to set lineWidth to %f but physical device wideLines feature "
                                             "not supported/enabled so lineWidth must be 1.0f!",
@@ -3217,17 +3245,17 @@
 }
 
 // Verify that create state for a pipeline is valid
-static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device, std::vector<PIPELINE_NODE *> pPipelines,
+static bool verifyPipelineCreateState(layer_data *my_data, const VkDevice device, std::vector<PIPELINE_STATE *> pPipelines,
                                       int pipelineIndex) {
     bool skip_call = false;
 
-    PIPELINE_NODE *pPipeline = pPipelines[pipelineIndex];
+    PIPELINE_STATE *pPipeline = pPipelines[pipelineIndex];
 
     // If create derivative bit is set, check that we've specified a base
     // pipeline correctly, and that the base pipeline was created to allow
     // derivatives.
     if (pPipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT) {
-        PIPELINE_NODE *pBasePipeline = nullptr;
+        PIPELINE_STATE *pBasePipeline = nullptr;
         if (!((pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) ^
               (pPipeline->graphicsPipelineCI.basePipelineIndex != -1))) {
             skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -3243,7 +3271,7 @@
                 pBasePipeline = pPipelines[pPipeline->graphicsPipelineCI.basePipelineIndex];
             }
         } else if (pPipeline->graphicsPipelineCI.basePipelineHandle != VK_NULL_HANDLE) {
-            pBasePipeline = getPipeline(my_data, pPipeline->graphicsPipelineCI.basePipelineHandle);
+            pBasePipeline = getPipelineState(my_data, pPipeline->graphicsPipelineCI.basePipelineHandle);
         }
 
         if (pBasePipeline && !(pBasePipeline->graphicsPipelineCI.flags & VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT)) {
@@ -3254,7 +3282,7 @@
     }
 
     if (pPipeline->graphicsPipelineCI.pColorBlendState != NULL) {
-        if (!my_data->phys_dev_properties.features.independentBlend) {
+        if (!my_data->enabled_features.independentBlend) {
             if (pPipeline->attachments.size() > 1) {
                 VkPipelineColorBlendAttachmentState *pAttachments = &pPipeline->attachments[0];
                 for (size_t i = 1; i < pPipeline->attachments.size(); i++) {
@@ -3272,36 +3300,27 @@
                 }
             }
         }
-        if (!my_data->phys_dev_properties.features.logicOp &&
+        if (!my_data->enabled_features.logicOp &&
             (pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable != VK_FALSE)) {
             skip_call |=
                 log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_DISABLED_LOGIC_OP, "DS",
                         "Invalid Pipeline CreateInfo: If logic operations feature not enabled, logicOpEnable must be VK_FALSE");
         }
-        if ((pPipeline->graphicsPipelineCI.pColorBlendState->logicOpEnable == VK_TRUE) &&
-            ((pPipeline->graphicsPipelineCI.pColorBlendState->logicOp < VK_LOGIC_OP_CLEAR) ||
-             (pPipeline->graphicsPipelineCI.pColorBlendState->logicOp > VK_LOGIC_OP_SET))) {
-            skip_call |=
-                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                        DRAWSTATE_INVALID_LOGIC_OP, "DS",
-                        "Invalid Pipeline CreateInfo: If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value");
-        }
     }
 
     // Ensure the subpass index is valid. If not, then validate_and_capture_pipeline_shader_state
     // produces nonsense errors that confuse users. Other layers should already
     // emit errors for renderpass being invalid.
-    auto renderPass = getRenderPass(my_data, pPipeline->graphicsPipelineCI.renderPass);
-    if (renderPass &&
-        pPipeline->graphicsPipelineCI.subpass >= renderPass->pCreateInfo->subpassCount) {
+    auto renderPass = getRenderPassState(my_data, pPipeline->graphicsPipelineCI.renderPass);
+    if (renderPass && pPipeline->graphicsPipelineCI.subpass >= renderPass->createInfo.subpassCount) {
         skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Subpass index %u "
                                                                             "is out of range for this renderpass (0..%u)",
-                             pPipeline->graphicsPipelineCI.subpass, renderPass->pCreateInfo->subpassCount - 1);
+                             pPipeline->graphicsPipelineCI.subpass, renderPass->createInfo.subpassCount - 1);
     }
 
-    if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->phys_dev_properties.features,
+    if (!validate_and_capture_pipeline_shader_state(my_data->report_data, pPipeline, &my_data->enabled_features,
                                                     my_data->shaderModuleMap)) {
         skip_call = true;
     }
@@ -3320,7 +3339,7 @@
     if (!(pPipeline->active_shaders & VK_SHADER_STAGE_VERTEX_BIT)) {
         skip_call |=
             log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                    DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Vtx Shader required");
+                    DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, "DS", "Invalid Pipeline CreateInfo State: Vertex Shader required");
     }
     // Either both or neither TC/TE shaders should be defined
     if (((pPipeline->active_shaders & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) == 0) !=
@@ -3376,7 +3395,8 @@
     // If a rasterization state is provided, make sure that the line width conforms to the HW.
     if (pPipeline->graphicsPipelineCI.pRasterizationState) {
         if (!isDynamic(pPipeline, VK_DYNAMIC_STATE_LINE_WIDTH)) {
-            skip_call |= verifyLineWidth(my_data, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE, reinterpret_cast<uint64_t &>(pPipeline),
+            skip_call |= verifyLineWidth(my_data, DRAWSTATE_INVALID_PIPELINE_CREATE_STATE,
+                                         reinterpret_cast<uint64_t const &>(pPipeline->pipeline),
                                          pPipeline->graphicsPipelineCI.pRasterizationState->lineWidth);
         }
     }
@@ -3428,7 +3448,7 @@
 
         // If rasterization is not disabled, and subpass uses a depth/stencil
         // attachment, pDepthStencilState must be a pointer to a valid structure
-        auto subpass_desc = renderPass ? &renderPass->pCreateInfo->pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
+        auto subpass_desc = renderPass ? &renderPass->createInfo.pSubpasses[pPipeline->graphicsPipelineCI.subpass] : nullptr;
         if (subpass_desc && subpass_desc->pDepthStencilAttachment &&
             subpass_desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
             if (!pPipeline->graphicsPipelineCI.pDepthStencilState) {
@@ -3456,7 +3476,7 @@
 // Block of code at start here specifically for managing/tracking DSs
 
 // Return Pool node ptr for specified pool or else NULL
-DESCRIPTOR_POOL_NODE *getPoolNode(const layer_data *dev_data, const VkDescriptorPool pool) {
+DESCRIPTOR_POOL_STATE *getDescriptorPoolState(const layer_data *dev_data, const VkDescriptorPool pool) {
     auto pool_it = dev_data->descriptorPoolMap.find(pool);
     if (pool_it == dev_data->descriptorPoolMap.end()) {
         return NULL;
@@ -3625,13 +3645,13 @@
     auto sub_data = my_data->imageSubresourceMap.find(image);
     if (sub_data == my_data->imageSubresourceMap.end())
         return false;
-    auto img_node = getImageNode(my_data, image);
-    if (!img_node)
+    auto image_state = getImageState(my_data, image);
+    if (!image_state)
         return false;
     bool ignoreGlobal = false;
     // TODO: Make this robust for >1 aspect mask. Now it will just say ignore
     // potential errors in this case.
-    if (sub_data->second.size() >= (img_node->createInfo.arrayLayers * img_node->createInfo.mipLevels + 1)) {
+    if (sub_data->second.size() >= (image_state->createInfo.arrayLayers * image_state->createInfo.mipLevels + 1)) {
         ignoreGlobal = true;
     }
     for (auto imgsubpair : sub_data->second) {
@@ -3707,10 +3727,10 @@
 }
 
 void SetLayout(const layer_data *dev_data, GLOBAL_CB_NODE *pCB, VkImageView imageView, const VkImageLayout &layout) {
-    auto iv_data = getImageViewData(dev_data, imageView);
-    assert(iv_data);
-    const VkImage &image = iv_data->image;
-    const VkImageSubresourceRange &subRange = iv_data->subresourceRange;
+    auto view_state = getImageViewState(dev_data, imageView);
+    assert(view_state);
+    auto image = view_state->create_info.image;
+    const VkImageSubresourceRange &subRange = view_state->create_info.subresourceRange;
     // TODO: Do not iterate over every possibility - consolidate where possible
     for (uint32_t j = 0; j < subRange.levelCount; j++) {
         uint32_t level = subRange.baseMipLevel + j;
@@ -3721,7 +3741,7 @@
             // the aspectMask is ignored and both are used. Verify that the extra implicit layout
             // is OK for descriptor set layout validation
             if (subRange.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
-                if (vk_format_is_depth_and_stencil(iv_data->format)) {
+                if (vk_format_is_depth_and_stencil(view_state->create_info.format)) {
                     sub.aspectMask |= (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
                 }
             }
@@ -3734,20 +3754,24 @@
 // func_str is the name of the calling function
 // Return false if no errors occur
 // Return true if validation error occurs and callback returns true (to skip upcoming API call down the chain)
-static bool validateIdleDescriptorSet(const layer_data *my_data, VkDescriptorSet set, std::string func_str) {
+static bool validateIdleDescriptorSet(const layer_data *dev_data, VkDescriptorSet set, std::string func_str) {
+    if (dev_data->instance_data->disabled.idle_descriptor_set)
+        return false;
     bool skip_call = false;
-    auto set_node = my_data->setMap.find(set);
-    if (set_node == my_data->setMap.end()) {
-        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+    auto set_node = dev_data->setMap.find(set);
+    if (set_node == dev_data->setMap.end()) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                              (uint64_t)(set), __LINE__, DRAWSTATE_DOUBLE_DESTROY, "DS",
                              "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that has not been allocated.", func_str.c_str(),
                              (uint64_t)(set));
     } else {
+        // TODO : This covers various error cases so should pass error enum into this function and use passed in enum here
         if (set_node->second->in_use.load()) {
-            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)(set), __LINE__, DRAWSTATE_OBJECT_INUSE,
-                                 "DS", "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that is in use by a command buffer.",
-                                 func_str.c_str(), (uint64_t)(set));
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+                        (uint64_t)(set), __LINE__, VALIDATION_ERROR_00919, "DS",
+                        "Cannot call %s() on descriptor set 0x%" PRIxLEAST64 " that is in use by a command buffer. %s",
+                        func_str.c_str(), (uint64_t)(set), validation_error_map[VALIDATION_ERROR_00919]);
         }
     }
     return skip_call;
@@ -3775,7 +3799,7 @@
 
 static void clearDescriptorPool(layer_data *my_data, const VkDevice device, const VkDescriptorPool pool,
                                 VkDescriptorPoolResetFlags flags) {
-    DESCRIPTOR_POOL_NODE *pPool = getPoolNode(my_data, pool);
+    DESCRIPTOR_POOL_STATE *pPool = getDescriptorPoolState(my_data, pool);
     // TODO: validate flags
     // For every set off of this pool, clear it, remove from setMap, and free cvdescriptorset::DescriptorSet
     for (auto ds : pPool->sets) {
@@ -3936,6 +3960,74 @@
     }
     return skip_call;
 }
+// For given object struct return a ptr of BASE_NODE type for its wrapping struct
+BASE_NODE *GetStateStructPtrFromObject(layer_data *dev_data, VK_OBJECT object_struct) {
+    BASE_NODE *base_ptr = nullptr;
+    switch (object_struct.type) {
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: {
+        base_ptr = getSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: {
+        base_ptr = getSamplerState(dev_data, reinterpret_cast<VkSampler &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: {
+        base_ptr = getQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: {
+        base_ptr = getPipelineState(dev_data, reinterpret_cast<VkPipeline &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
+        base_ptr = getBufferNode(dev_data, reinterpret_cast<VkBuffer &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: {
+        base_ptr = getBufferViewState(dev_data, reinterpret_cast<VkBufferView &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
+        base_ptr = getImageState(dev_data, reinterpret_cast<VkImage &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: {
+        base_ptr = getImageViewState(dev_data, reinterpret_cast<VkImageView &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: {
+        base_ptr = getEventNode(dev_data, reinterpret_cast<VkEvent &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: {
+        base_ptr = getDescriptorPoolState(dev_data, reinterpret_cast<VkDescriptorPool &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: {
+        base_ptr = getCommandPoolNode(dev_data, reinterpret_cast<VkCommandPool &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: {
+        base_ptr = getFramebufferState(dev_data, reinterpret_cast<VkFramebuffer &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: {
+        base_ptr = getRenderPassState(dev_data, reinterpret_cast<VkRenderPass &>(object_struct.handle));
+        break;
+    }
+    case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: {
+        base_ptr = getMemObjInfo(dev_data, reinterpret_cast<VkDeviceMemory &>(object_struct.handle));
+        break;
+    }
+    default:
+        // TODO : Any other objects to be handled here?
+        assert(0);
+        break;
+    }
+    return base_ptr;
+}
+
 // Tie the VK_OBJECT to the cmd buffer which includes:
 //  Add object_binding to cmd buffer
 //  Add cb_binding to object
@@ -3945,52 +4037,9 @@
 }
 // For a given object, if cb_node is in that objects cb_bindings, remove cb_node
 static void removeCommandBufferBinding(layer_data *dev_data, VK_OBJECT const *object, GLOBAL_CB_NODE *cb_node) {
-    switch (object->type) {
-    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
-        auto img_node = getImageNode(dev_data, reinterpret_cast<const VkImage &>(object->handle));
-        if (img_node)
-            img_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
-        auto buf_node = getBufferNode(dev_data, reinterpret_cast<const VkBuffer &>(object->handle));
-        if (buf_node)
-            buf_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: {
-        auto evt_node = getEventNode(dev_data, reinterpret_cast<const VkEvent &>(object->handle));
-        if (evt_node)
-            evt_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: {
-        auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast<const VkQueryPool &>(object->handle));
-        if (qp_node)
-            qp_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: {
-        auto pipe_node = getPipeline(dev_data, reinterpret_cast<const VkPipeline &>(object->handle));
-        if (pipe_node)
-            pipe_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: {
-        auto set_node = getSetNode(dev_data, reinterpret_cast<const VkDescriptorSet &>(object->handle));
-        if (set_node)
-            set_node->RemoveBoundCommandBuffer(cb_node);
-        break;
-    }
-    case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: {
-        auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<const VkSampler &>(object->handle));
-        if (sampler_node)
-            sampler_node->cb_bindings.erase(cb_node);
-        break;
-    }
-    default:
-        assert(0); // unhandled object type
-    }
+    BASE_NODE *base_obj = GetStateStructPtrFromObject(dev_data, *object);
+    if (base_obj)
+        base_obj->cb_bindings.erase(cb_node);
 }
 // Reset the command buffer state
 //  Maintain the createInfo and set state to CB_NEW, but clear all other state
@@ -4051,9 +4100,9 @@
         pCB->object_bindings.clear();
         // Remove this cmdBuffer's reference from each FrameBuffer's CB ref list
         for (auto framebuffer : pCB->framebuffers) {
-            auto fb_node = getFramebuffer(dev_data, framebuffer);
-            if (fb_node)
-                fb_node->cb_bindings.erase(pCB);
+            auto fb_state = getFramebufferState(dev_data, framebuffer);
+            if (fb_state)
+                fb_state->cb_bindings.erase(pCB);
         }
         pCB->framebuffers.clear();
         pCB->activeFramebuffer = VK_NULL_HANDLE;
@@ -4061,24 +4110,18 @@
 }
 
 // Set PSO-related status bits for CB, including dynamic state set via PSO
-static void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_NODE *pPipe) {
+static void set_cb_pso_status(GLOBAL_CB_NODE *pCB, const PIPELINE_STATE *pPipe) {
     // Account for any dynamic state not set via this PSO
     if (!pPipe->graphicsPipelineCI.pDynamicState ||
         !pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount) { // All state is static
-        pCB->status |= CBSTATUS_ALL;
+        pCB->status |= CBSTATUS_ALL_STATE_SET;
     } else {
         // First consider all state on
         // Then unset any state that's noted as dynamic in PSO
         // Finally OR that into CB statemask
-        CBStatusFlags psoDynStateMask = CBSTATUS_ALL;
+        CBStatusFlags psoDynStateMask = CBSTATUS_ALL_STATE_SET;
         for (uint32_t i = 0; i < pPipe->graphicsPipelineCI.pDynamicState->dynamicStateCount; i++) {
             switch (pPipe->graphicsPipelineCI.pDynamicState->pDynamicStates[i]) {
-            case VK_DYNAMIC_STATE_VIEWPORT:
-                psoDynStateMask &= ~CBSTATUS_VIEWPORT_SET;
-                break;
-            case VK_DYNAMIC_STATE_SCISSOR:
-                psoDynStateMask &= ~CBSTATUS_SCISSOR_SET;
-                break;
             case VK_DYNAMIC_STATE_LINE_WIDTH:
                 psoDynStateMask &= ~CBSTATUS_LINE_WIDTH_SET;
                 break;
@@ -4114,7 +4157,7 @@
     bool skip_call = false;
     GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb);
     if (pCB) {
-        PIPELINE_NODE *pPipeTrav = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline_node;
+        PIPELINE_STATE *pPipeTrav = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline_state;
         if (!pPipeTrav) {
             // nothing to print
         } else {
@@ -4132,10 +4175,10 @@
     GLOBAL_CB_NODE *pCB = getCBNode(my_data, cb);
     if (pCB && pCB->cmds.size() > 0) {
         log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                DRAWSTATE_NONE, "DS", "Cmds in CB 0x%p", (void *)cb);
+                DRAWSTATE_NONE, "DS", "Cmds in command buffer 0x%p", (void *)cb);
         vector<CMD_NODE> cmds = pCB->cmds;
         for (auto ii = cmds.begin(); ii != cmds.end(); ++ii) {
-            // TODO : Need to pass cb as srcObj here
+            // TODO : Need to pass cmdbuffer as srcObj here
             log_msg(my_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
                     __LINE__, DRAWSTATE_NONE, "DS", "  CMD 0x%" PRIx64 ": %s", (*ii).cmdNumber, cmdTypeToString((*ii).type).c_str());
         }
@@ -4180,12 +4223,45 @@
     return outside;
 }
 
-static void init_core_validation(layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
+static void init_core_validation(instance_layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
 
     layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "lunarg_core_validation");
 
 }
 
+static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, instance_layer_data *instance_data) {
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME))
+            instance_data->surfaceExtensionEnabled = true;
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME))
+            instance_data->displayExtensionEnabled = true;
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME))
+            instance_data->androidSurfaceExtensionEnabled = true;
+#endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME))
+            instance_data->mirSurfaceExtensionEnabled = true;
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME))
+            instance_data->waylandSurfaceExtensionEnabled = true;
+#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME))
+            instance_data->win32SurfaceExtensionEnabled = true;
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME))
+            instance_data->xcbSurfaceExtensionEnabled = true;
+#endif
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
+            instance_data->xlibSurfaceExtensionEnabled = true;
+#endif
+    }
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkInstance *pInstance) {
     VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
@@ -4203,17 +4279,15 @@
     if (result != VK_SUCCESS)
         return result;
 
-    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), instance_layer_data_map);
     instance_data->instance = *pInstance;
-    instance_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
-    layer_init_instance_dispatch_table(*pInstance, instance_data->instance_dispatch_table, fpGetInstanceProcAddr);
+    layer_init_instance_dispatch_table(*pInstance, &instance_data->dispatch_table, fpGetInstanceProcAddr);
 
-    instance_data->report_data =
-        debug_report_create_instance(instance_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
-                                     pCreateInfo->ppEnabledExtensionNames);
+    instance_data->report_data = debug_report_create_instance(
+        &instance_data->dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames);
+    checkInstanceRegisterExtensions(pCreateInfo, instance_data);
     init_core_validation(instance_data, pAllocator);
 
-    instance_data->instance_state = unique_ptr<INSTANCE_STATE>(new INSTANCE_STATE());
     ValidateLayerOrdering(*pCreateInfo);
 
     return result;
@@ -4225,20 +4299,18 @@
     dispatch_key key = get_dispatch_key(instance);
     // TBD: Need any locking this early, in case this function is called at the
     // same time by more than one thread?
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    pTable->DestroyInstance(instance, pAllocator);
+    instance_layer_data *instance_data = get_my_data_ptr(key, instance_layer_data_map);
+    instance_data->dispatch_table.DestroyInstance(instance, pAllocator);
 
     std::lock_guard<std::mutex> lock(global_lock);
     // Clean up logging callback, if any
-    while (my_data->logging_callback.size() > 0) {
-        VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
-        layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
-        my_data->logging_callback.pop_back();
+    while (instance_data->logging_callback.size() > 0) {
+        VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
+        layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+        instance_data->logging_callback.pop_back();
     }
 
-    layer_debug_report_destroy_instance(my_data->report_data);
-    delete my_data->instance_dispatch_table;
+    layer_debug_report_destroy_instance(instance_data->report_data);
     layer_data_map.erase(key);
 }
 
@@ -4259,36 +4331,36 @@
 }
 
 // Verify that queue family has been properly requested
-bool ValidateRequestedQueueFamilyProperties(layer_data *dev_data, const VkDeviceCreateInfo *create_info) {
+bool ValidateRequestedQueueFamilyProperties(instance_layer_data *instance_data, VkPhysicalDevice gpu, const VkDeviceCreateInfo *create_info) {
     bool skip_call = false;
+    auto physical_device_state = getPhysicalDeviceState(instance_data, gpu);
     // First check is app has actually requested queueFamilyProperties
-    if (!dev_data->physical_device_state) {
-        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+    if (!physical_device_state) {
+        skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
                              0, __LINE__, DEVLIMITS_MUST_QUERY_COUNT, "DL",
                              "Invalid call to vkCreateDevice() w/o first calling vkEnumeratePhysicalDevices().");
-    } else if (QUERY_DETAILS != dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
+    } else if (QUERY_DETAILS != physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
         // TODO: This is not called out as an invalid use in the spec so make more informative recommendation.
-        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+        skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
                              VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST,
                              "DL", "Call to vkCreateDevice() w/o first calling vkGetPhysicalDeviceQueueFamilyProperties().");
     } else {
         // Check that the requested queue properties are valid
         for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
             uint32_t requestedIndex = create_info->pQueueCreateInfos[i].queueFamilyIndex;
-            if (dev_data->queue_family_properties.size() <=
-                requestedIndex) { // requested index is out of bounds for this physical device
+            if (requestedIndex >= physical_device_state->queue_family_properties.size()) {
                 skip_call |= log_msg(
-                    dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
+                    instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
                     __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
                     "Invalid queue create request in vkCreateDevice(). Invalid queueFamilyIndex %u requested.", requestedIndex);
             } else if (create_info->pQueueCreateInfos[i].queueCount >
-                       dev_data->queue_family_properties[requestedIndex]->queueCount) {
+                       physical_device_state->queue_family_properties[requestedIndex].queueCount) {
                 skip_call |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
+                    log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT,
                             0, __LINE__, DEVLIMITS_INVALID_QUEUE_CREATE_REQUEST, "DL",
                             "Invalid queue create request in vkCreateDevice(). QueueFamilyIndex %u only has %u queues, but "
                             "requested queueCount is %u.",
-                            requestedIndex, dev_data->queue_family_properties[requestedIndex]->queueCount,
+                            requestedIndex, physical_device_state->queue_family_properties[requestedIndex].queueCount,
                             create_info->pQueueCreateInfos[i].queueCount);
             }
         }
@@ -4297,10 +4369,11 @@
 }
 
 // Verify that features have been queried and that they are available
-static bool ValidateRequestedFeatures(layer_data *dev_data, const VkPhysicalDeviceFeatures *requested_features) {
+static bool ValidateRequestedFeatures(instance_layer_data *dev_data, VkPhysicalDevice phys, const VkPhysicalDeviceFeatures *requested_features) {
     bool skip_call = false;
 
-    VkBool32 *actual = reinterpret_cast<VkBool32 *>(&(dev_data->physical_device_features));
+    auto phys_device_state = getPhysicalDeviceState(dev_data, phys);
+    const VkBool32 *actual = reinterpret_cast<VkBool32 *>(&phys_device_state->features);
     const VkBool32 *requested = reinterpret_cast<const VkBool32 *>(requested_features);
     // TODO : This is a nice, compact way to loop through struct, but a bad way to report issues
     //  Need to provide the struct member name with the issue. To do that seems like we'll
@@ -4318,7 +4391,7 @@
             errors++;
         }
     }
-    if (errors && (UNCALLED == dev_data->physical_device_state->vkGetPhysicalDeviceFeaturesState)) {
+    if (errors && (UNCALLED == phys_device_state->vkGetPhysicalDeviceFeaturesState)) {
         // If user didn't request features, notify them that they should
         // TODO: Verify this against the spec. I believe this is an invalid use of the API and should return an error
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -4331,14 +4404,14 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
                                             const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
-    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+    instance_layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), instance_layer_data_map);
     bool skip_call = false;
 
     // Check that any requested features are available
     if (pCreateInfo->pEnabledFeatures) {
-        skip_call |= ValidateRequestedFeatures(my_instance_data, pCreateInfo->pEnabledFeatures);
+        skip_call |= ValidateRequestedFeatures(my_instance_data, gpu, pCreateInfo->pEnabledFeatures);
     }
-    skip_call |= ValidateRequestedQueueFamilyProperties(my_instance_data, pCreateInfo);
+    skip_call |= ValidateRequestedQueueFamilyProperties(my_instance_data, gpu, pCreateInfo);
 
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -4365,28 +4438,28 @@
     std::unique_lock<std::mutex> lock(global_lock);
     layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
 
+    my_device_data->instance_data = my_instance_data;
     // Setup device dispatch table
-    my_device_data->device_dispatch_table = new VkLayerDispatchTable;
-    layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+    layer_init_device_dispatch_table(*pDevice, &my_device_data->dispatch_table, fpGetDeviceProcAddr);
     my_device_data->device = *pDevice;
 
     my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
     checkDeviceRegisterExtensions(pCreateInfo, *pDevice);
     // Get physical device limits for this device
-    my_instance_data->instance_dispatch_table->GetPhysicalDeviceProperties(gpu, &(my_device_data->phys_dev_properties.properties));
+    my_instance_data->dispatch_table.GetPhysicalDeviceProperties(gpu, &(my_device_data->phys_dev_properties.properties));
     uint32_t count;
-    my_instance_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
+    my_instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(gpu, &count, nullptr);
     my_device_data->phys_dev_properties.queue_family_properties.resize(count);
-    my_instance_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(
+    my_instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(
         gpu, &count, &my_device_data->phys_dev_properties.queue_family_properties[0]);
     // TODO: device limits should make sure these are compatible
     if (pCreateInfo->pEnabledFeatures) {
-        my_device_data->phys_dev_properties.features = *pCreateInfo->pEnabledFeatures;
+        my_device_data->enabled_features = *pCreateInfo->pEnabledFeatures;
     } else {
-        memset(&my_device_data->phys_dev_properties.features, 0, sizeof(VkPhysicalDeviceFeatures));
+        memset(&my_device_data->enabled_features, 0, sizeof(VkPhysicalDeviceFeatures));
     }
     // Store physical device mem limits into device layer_data struct
-    my_instance_data->instance_dispatch_table->GetPhysicalDeviceMemoryProperties(gpu, &my_device_data->phys_dev_mem_props);
+    my_instance_data->dispatch_table.GetPhysicalDeviceMemoryProperties(gpu, &my_device_data->phys_dev_mem_props);
     lock.unlock();
 
     ValidateLayerOrdering(*pCreateInfo);
@@ -4395,15 +4468,15 @@
 }
 
 // prototype
-static void deleteRenderPasses(layer_data *);
 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
     // TODOSC : Shouldn't need any customization here
+    bool skip = false;
     dispatch_key key = get_dispatch_key(device);
     layer_data *dev_data = get_my_data_ptr(key, layer_data_map);
     // Free all the memory
     std::unique_lock<std::mutex> lock(global_lock);
     deletePipelines(dev_data);
-    deleteRenderPasses(dev_data);
+    dev_data->renderPassMap.clear();
     deleteCommandBuffers(dev_data);
     // This will also delete all sets in the pool & remove them from setMap
     deletePools(dev_data);
@@ -4421,10 +4494,6 @@
     dev_data->bufferMap.clear();
     // Queues persist until device is destroyed
     dev_data->queueMap.clear();
-    lock.unlock();
-#if MTMERGESOURCE
-    bool skip_call = false;
-    lock.lock();
     log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
             (uint64_t)device, __LINE__, MEMTRACK_NONE, "MEM", "Printing List details prior to vkDestroyDevice()");
     log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
@@ -4438,12 +4507,11 @@
             pInfo = (*ii).second.get();
             if (pInfo->alloc_info.allocationSize != 0) {
                 // Valid Usage: All child objects created on device must have been destroyed prior to destroying device
-                skip_call |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                            (uint64_t)pInfo->mem, __LINE__, MEMTRACK_MEMORY_LEAK, "MEM",
-                            "Mem Object 0x%" PRIx64 " has not been freed. You should clean up this memory by calling "
-                            "vkFreeMemory(0x%" PRIx64 ") prior to vkDestroyDevice().",
-                            (uint64_t)(pInfo->mem), (uint64_t)(pInfo->mem));
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                                (uint64_t)pInfo->mem, __LINE__, MEMTRACK_MEMORY_LEAK, "MEM",
+                                "Mem Object 0x%" PRIx64 " has not been freed. You should clean up this memory by calling "
+                                "vkFreeMemory(0x%" PRIx64 ") prior to vkDestroyDevice().",
+                                (uint64_t)(pInfo->mem), (uint64_t)(pInfo->mem));
             }
         }
     }
@@ -4453,15 +4521,10 @@
 #if DISPATCH_MAP_DEBUG
     fprintf(stderr, "Device: 0x%p, key: 0x%p\n", device, key);
 #endif
-    VkLayerDispatchTable *pDisp = dev_data->device_dispatch_table;
-    if (!skip_call) {
-        pDisp->DestroyDevice(device, pAllocator);
+    if (!skip) {
+        dev_data->dispatch_table.DestroyDevice(device, pAllocator);
+        layer_data_map.erase(key);
     }
-#else
-    dev_data->device_dispatch_table->DestroyDevice(device, pAllocator);
-#endif
-    delete dev_data->device_dispatch_table;
-    layer_data_map.erase(key);
 }
 
 static const VkExtensionProperties instance_extensions[] = {{VK_EXT_DEBUG_REPORT_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_SPEC_VERSION}};
@@ -4511,93 +4574,94 @@
 // Loop through bound objects and increment their in_use counts
 //  For any unknown objects, flag an error
 static bool ValidateAndIncrementBoundObjects(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) {
-    bool skip_call = false;
+    bool skip = false;
+    DRAW_STATE_ERROR error_code = DRAWSTATE_NONE;
+    BASE_NODE *base_obj = nullptr;
     for (auto obj : cb_node->object_bindings) {
         switch (obj.type) {
         case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: {
-            auto set_node = getSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(obj.handle));
-            if (!set_node) {
-                skip_call |=
-                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                            obj.handle, __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
-                            "Cannot submit cmd buffer using deleted descriptor set 0x%" PRIx64 ".", obj.handle);
-            } else {
-                set_node->in_use.fetch_add(1);
-            }
+            base_obj = getSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_DESCRIPTOR_SET;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: {
-            auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<VkSampler &>(obj.handle));
-            if (!sampler_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT,
-                                     obj.handle, __LINE__, DRAWSTATE_INVALID_SAMPLER, "DS",
-                                     "Cannot submit cmd buffer using deleted sampler 0x%" PRIx64 ".", obj.handle);
-            } else {
-                sampler_node->in_use.fetch_add(1);
-            }
+            base_obj = getSamplerState(dev_data, reinterpret_cast<VkSampler &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_SAMPLER;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: {
-            auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(obj.handle));
-            if (!qp_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                     VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, obj.handle, __LINE__, MEMTRACK_INVALID_OBJECT,
-                                     "DS", "Cannot submit cmd buffer using deleted query pool 0x%" PRIx64 ".", obj.handle);
-            } else {
-                qp_node->in_use.fetch_add(1);
-            }
+            base_obj = getQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_QUERY_POOL;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: {
-            auto pipe_node = getPipeline(dev_data, reinterpret_cast<VkPipeline &>(obj.handle));
-            if (!pipe_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT,
-                                     obj.handle, __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS",
-                                     "Cannot submit cmd buffer using deleted pipeline 0x%" PRIx64 ".", obj.handle);
-            } else {
-                pipe_node->in_use.fetch_add(1);
-            }
+            base_obj = getPipelineState(dev_data, reinterpret_cast<VkPipeline &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_PIPELINE;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
-            auto buff_node = getBufferNode(dev_data, reinterpret_cast<VkBuffer &>(obj.handle));
-            if (!buff_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
-                                     obj.handle, __LINE__, DRAWSTATE_INVALID_BUFFER, "DS",
-                                     "Cannot submit cmd buffer using deleted buffer 0x%" PRIx64 ".", obj.handle);
-            } else {
-                buff_node->in_use.fetch_add(1);
-            }
+            base_obj = getBufferNode(dev_data, reinterpret_cast<VkBuffer &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_BUFFER;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT: {
+            base_obj = getBufferViewState(dev_data, reinterpret_cast<VkBufferView &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_BUFFER_VIEW;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
-            auto image_node = getImageNode(dev_data, reinterpret_cast<VkImage &>(obj.handle));
-            if (!image_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
-                                     obj.handle, __LINE__, DRAWSTATE_INVALID_IMAGE, "DS",
-                                     "Cannot submit cmd buffer using deleted image 0x%" PRIx64 ".", obj.handle);
-            } else {
-                image_node->in_use.fetch_add(1);
-            }
+            base_obj = getImageState(dev_data, reinterpret_cast<VkImage &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_IMAGE;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT: {
+            base_obj = getImageViewState(dev_data, reinterpret_cast<VkImageView &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_IMAGE_VIEW;
             break;
         }
         case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: {
-            auto event_node = getEventNode(dev_data, reinterpret_cast<VkEvent &>(obj.handle));
-            if (!event_node) {
-                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
-                                     obj.handle, __LINE__, DRAWSTATE_INVALID_EVENT, "DS",
-                                     "Cannot submit cmd buffer using deleted event 0x%" PRIx64 ".", obj.handle);
-            } else {
-                event_node->in_use.fetch_add(1);
-            }
+            base_obj = getEventNode(dev_data, reinterpret_cast<VkEvent &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_EVENT;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT: {
+            base_obj = getDescriptorPoolState(dev_data, reinterpret_cast<VkDescriptorPool &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_DESCRIPTOR_POOL;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT: {
+            base_obj = getCommandPoolNode(dev_data, reinterpret_cast<VkCommandPool &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_COMMAND_POOL;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT: {
+            base_obj = getFramebufferState(dev_data, reinterpret_cast<VkFramebuffer &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_FRAMEBUFFER;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT: {
+            base_obj = getRenderPassState(dev_data, reinterpret_cast<VkRenderPass &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_RENDERPASS;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT: {
+            base_obj = getMemObjInfo(dev_data, reinterpret_cast<VkDeviceMemory &>(obj.handle));
+            error_code = DRAWSTATE_INVALID_DEVICE_MEMORY;
             break;
         }
         default:
             // TODO : Merge handling of other objects types into this code
             break;
         }
+        if (!base_obj) {
+            skip |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj.type, obj.handle, __LINE__, error_code, "DS",
+                        "Cannot submit cmd buffer using deleted %s 0x%" PRIx64 ".", object_type_to_string(obj.type), obj.handle);
+        } else {
+            base_obj->in_use.fetch_add(1);
+        }
     }
-    return skip_call;
+    return skip;
 }
 
 // Track which resources are in-flight by atomically incrementing their "in_use" count
@@ -4625,9 +4689,9 @@
         }
     }
     for (auto event : cb_node->writeEventsBeforeWait) {
-        auto event_node = getEventNode(dev_data, event);
-        if (event_node)
-            event_node->write_in_use++;
+        auto event_state = getEventNode(dev_data, event);
+        if (event_state)
+            event_state->write_in_use++;
     }
     return skip_call;
 }
@@ -4667,60 +4731,11 @@
 
 // Decrement in-use count for objects bound to command buffer
 static void DecrementBoundResources(layer_data *dev_data, GLOBAL_CB_NODE const *cb_node) {
+    BASE_NODE *base_obj = nullptr;
     for (auto obj : cb_node->object_bindings) {
-        switch (obj.type) {
-        case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT: {
-            auto set_node = getSetNode(dev_data, reinterpret_cast<VkDescriptorSet &>(obj.handle));
-            if (set_node) {
-                set_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT: {
-            auto sampler_node = getSamplerNode(dev_data, reinterpret_cast<VkSampler &>(obj.handle));
-            if (sampler_node) {
-                sampler_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT: {
-            auto qp_node = getQueryPoolNode(dev_data, reinterpret_cast<VkQueryPool &>(obj.handle));
-            if (qp_node) {
-                qp_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT: {
-            auto pipe_node = getPipeline(dev_data, reinterpret_cast<VkPipeline &>(obj.handle));
-            if (pipe_node) {
-                pipe_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
-            auto buff_node = getBufferNode(dev_data, reinterpret_cast<VkBuffer &>(obj.handle));
-            if (buff_node) {
-                buff_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
-            auto image_node = getImageNode(dev_data, reinterpret_cast<VkImage &>(obj.handle));
-            if (image_node) {
-                image_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT: {
-            auto event_node = getEventNode(dev_data, reinterpret_cast<VkEvent &>(obj.handle));
-            if (event_node) {
-                event_node->in_use.fetch_sub(1);
-            }
-            break;
-        }
-        default:
-            // TODO : Merge handling of other objects types into this code
-            break;
+        base_obj = GetStateStructPtrFromObject(dev_data, obj);
+        if (base_obj) {
+            base_obj->in_use.fetch_sub(1);
         }
     }
 }
@@ -4816,15 +4831,17 @@
     return skip_call;
 }
 
-static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB) {
-    bool skip_call = false;
+static bool validateCommandBufferState(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const char *call_source) {
+    bool skip = false;
+    if (dev_data->instance_data->disabled.command_buffer_state)
+        return skip;
     // Validate ONE_TIME_SUBMIT_BIT CB is not being submitted more than once
     if ((pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT) && (pCB->submitCount > 1)) {
-        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                             0, __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
-                             "CB 0x%" PRIxLEAST64 " was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT "
-                             "set, but has been submitted 0x%" PRIxLEAST64 " times.",
-                             (uint64_t)(pCB->commandBuffer), pCB->submitCount);
+        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
+                        __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
+                        "Commandbuffer 0x%" PRIxLEAST64 " was begun w/ VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT "
+                        "set, but has been submitted 0x%" PRIxLEAST64 " times.",
+                        (uint64_t)(pCB->commandBuffer), pCB->submitCount);
     }
     // Validate that cmd buffers have been updated
     if (CB_RECORDED != pCB->state) {
@@ -4836,7 +4853,7 @@
                 const char *cause_str =
                     (obj.type == VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT) ? "destroyed or updated" : "destroyed";
 
-                skip_call |=
+                skip |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t &>(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
                             "You are submitting command buffer 0x%" PRIxLEAST64 " that is invalid because bound %s 0x%" PRIxLEAST64
@@ -4844,14 +4861,13 @@
                             reinterpret_cast<uint64_t &>(pCB->commandBuffer), type_str, obj.handle, cause_str);
             }
         } else { // Flag error for using CB w/o vkEndCommandBuffer() called
-            skip_call |=
-                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                        (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS",
-                        "You must call vkEndCommandBuffer() on CB 0x%" PRIxLEAST64 " before this call to vkQueueSubmit()!",
-                        (uint64_t)(pCB->commandBuffer));
+            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_NO_END_COMMAND_BUFFER, "DS",
+                            "You must call vkEndCommandBuffer() on command buffer 0x%" PRIxLEAST64 " before this call to %s!",
+                            reinterpret_cast<uint64_t &>(pCB->commandBuffer), call_source);
         }
     }
-    return skip_call;
+    return skip;
 }
 
 // Validate that queueFamilyIndices of primary command buffers match this queue
@@ -4891,7 +4907,7 @@
                 !(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
                         __LINE__, DRAWSTATE_COMMAND_BUFFER_SINGLE_SUBMIT_VIOLATION, "DS",
-                        "CB 0x%" PRIxLEAST64 " was submitted with secondary buffer 0x%" PRIxLEAST64
+                        "Commandbuffer 0x%" PRIxLEAST64 " was submitted with secondary buffer 0x%" PRIxLEAST64
                         " but that buffer has subsequently been bound to "
                         "primary cmd buffer 0x%" PRIxLEAST64
                         " and it does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set.",
@@ -4901,7 +4917,7 @@
         }
     }
 
-    skip_call |= validateCommandBufferState(dev_data, pCB);
+    skip_call |= validateCommandBufferState(dev_data, pCB, "vkQueueSubmit()");
 
     return skip_call;
 }
@@ -5005,28 +5021,28 @@
         std::vector<VkCommandBuffer> cbs;
 
         for (uint32_t i = 0; i < submit->commandBufferCount; i++) {
-            auto pCBNode = getCBNode(dev_data, submit->pCommandBuffers[i]);
-            skip_call |= ValidateCmdBufImageLayouts(dev_data, pCBNode);
-            if (pCBNode) {
+            auto cb_node = getCBNode(dev_data, submit->pCommandBuffers[i]);
+            skip_call |= ValidateCmdBufImageLayouts(dev_data, cb_node);
+            if (cb_node) {
                 cbs.push_back(submit->pCommandBuffers[i]);
-                for (auto secondaryCmdBuffer : pCBNode->secondaryCommandBuffers) {
+                for (auto secondaryCmdBuffer : cb_node->secondaryCommandBuffers) {
                     cbs.push_back(secondaryCmdBuffer);
                 }
 
-                pCBNode->submitCount++; // increment submit count
-                skip_call |= validatePrimaryCommandBufferState(dev_data, pCBNode);
-                skip_call |= validateQueueFamilyIndices(dev_data, pCBNode, queue);
+                cb_node->submitCount++; // increment submit count
+                skip_call |= validatePrimaryCommandBufferState(dev_data, cb_node);
+                skip_call |= validateQueueFamilyIndices(dev_data, cb_node, queue);
                 // Potential early exit here as bad object state may crash in delayed function calls
                 if (skip_call)
                     return result;
                 // Call submit-time functions to validate/update state
-                for (auto &function : pCBNode->validate_functions) {
+                for (auto &function : cb_node->validate_functions) {
                     skip_call |= function();
                 }
-                for (auto &function : pCBNode->eventUpdates) {
+                for (auto &function : cb_node->eventUpdates) {
                     skip_call |= function(queue);
                 }
-                for (auto &function : pCBNode->queryUpdates) {
+                for (auto &function : cb_node->queryUpdates) {
                     skip_call |= function(queue);
                 }
             }
@@ -5048,7 +5064,7 @@
 
     lock.unlock();
     if (!skip_call)
-        result = dev_data->device_dispatch_table->QueueSubmit(queue, submitCount, pSubmits, fence);
+        result = dev_data->dispatch_table.QueueSubmit(queue, submitCount, pSubmits, fence);
 
     return result;
 }
@@ -5056,7 +5072,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
                                               const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = my_data->device_dispatch_table->AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
+    VkResult result = my_data->dispatch_table.AllocateMemory(device, pAllocateInfo, pAllocator, pMemory);
     // TODO : Track allocations and overall size here
     std::lock_guard<std::mutex> lock(global_lock);
     add_mem_obj_info(my_data, device, *pMemory, pAllocateInfo);
@@ -5064,24 +5080,72 @@
     return result;
 }
 
-VKAPI_ATTR void VKAPI_CALL
-FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+// For given obj node, if it is use, flag a validation error and return callback result, else return false
+bool ValidateObjectNotInUse(const layer_data *dev_data, BASE_NODE *obj_node, VK_OBJECT obj_struct,
+                            UNIQUE_VALIDATION_ERROR_CODE error_code) {
+    if (dev_data->instance_data->disabled.object_in_use)
+        return false;
+    bool skip = false;
+    if (obj_node->in_use.load()) {
+        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_struct.type, obj_struct.handle, __LINE__,
+                        error_code, "DS", "Cannot delete %s 0x%" PRIx64 " that is currently in use by a command buffer. %s",
+                        object_type_to_string(obj_struct.type), obj_struct.handle, validation_error_map[error_code]);
+    }
+    return skip;
+}
 
-    // From spec : A memory object is freed by calling vkFreeMemory() when it is no longer needed.
-    // Before freeing a memory object, an application must ensure the memory object is no longer
-    // in use by the device—for example by command buffers queued for execution. The memory need
-    // not yet be unbound from all images and buffers, but any further use of those images or
-    // buffers (on host or device) for anything other than destroying those objects will result in
-    // undefined behavior.
+static bool PreCallValidateFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO **mem_info, VK_OBJECT *obj_struct) {
+    *mem_info = getMemObjInfo(dev_data, mem);
+    *obj_struct = {reinterpret_cast<uint64_t &>(mem), VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT};
+    if (dev_data->instance_data->disabled.free_memory)
+        return false;
+    bool skip = false;
+    if (*mem_info) {
+        skip |= ValidateObjectNotInUse(dev_data, *mem_info, *obj_struct, VALIDATION_ERROR_00620);
+    }
+    return skip;
+}
 
+static void PostCallRecordFreeMemory(layer_data *dev_data, VkDeviceMemory mem, DEVICE_MEM_INFO *mem_info, VK_OBJECT obj_struct) {
+    // Clear mem binding for any bound objects
+    for (auto obj : mem_info->obj_bindings) {
+        log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, obj.type, obj.handle, __LINE__, MEMTRACK_FREED_MEM_REF,
+                "MEM", "VK Object 0x%" PRIxLEAST64 " still has a reference to mem obj 0x%" PRIxLEAST64, obj.handle,
+                (uint64_t)mem_info->mem);
+        switch (obj.type) {
+        case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT: {
+            auto image_state = getImageState(dev_data, reinterpret_cast<VkImage &>(obj.handle));
+            assert(image_state); // Any destroyed images should already be removed from bindings
+            image_state->binding.mem = MEMORY_UNBOUND;
+            break;
+        }
+        case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT: {
+            auto buff_node = getBufferNode(dev_data, reinterpret_cast<VkBuffer &>(obj.handle));
+            assert(buff_node); // Any destroyed buffers should already be removed from bindings
+            buff_node->binding.mem = MEMORY_UNBOUND;
+            break;
+        }
+        default:
+            // Should only have buffer or image objects bound to memory
+            assert(0);
+        }
+    }
+    // Any bound cmd buffers are now invalid
+    invalidateCommandBuffers(mem_info->cb_bindings, obj_struct);
+    dev_data->memObjMap.erase(mem);
+}
+
+VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory mem, const VkAllocationCallbacks *pAllocator) {
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    DEVICE_MEM_INFO *mem_info = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    bool skip_call = freeMemObjInfo(my_data, device, mem, false);
-    print_mem_list(my_data);
-    printCBList(my_data);
-    lock.unlock();
-    if (!skip_call) {
-        my_data->device_dispatch_table->FreeMemory(device, mem, pAllocator);
+    bool skip = PreCallValidateFreeMemory(dev_data, mem, &mem_info, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.FreeMemory(device, mem, pAllocator);
+        lock.lock();
+        PostCallRecordFreeMemory(dev_data, mem, mem_info, obj_struct);
     }
 }
 
@@ -5182,7 +5246,7 @@
             // From spec: (ppData - offset) must be aligned to at least limits::minMemoryMapAlignment.
             uint64_t start_offset = offset % map_alignment;
             // Data passed to driver will be wrapped by a guardband of data to detect over- or under-writes.
-            mem_info->shadow_copy_base = malloc(2 * mem_info->shadow_pad_size + size + map_alignment + start_offset);
+            mem_info->shadow_copy_base = malloc(static_cast<size_t>(2 * mem_info->shadow_pad_size + size + map_alignment + start_offset));
 
             mem_info->shadow_copy =
                 reinterpret_cast<char *>((reinterpret_cast<uintptr_t>(mem_info->shadow_copy_base) + map_alignment) &
@@ -5190,7 +5254,7 @@
             assert(vk_safe_modulo(reinterpret_cast<uintptr_t>(mem_info->shadow_copy) + mem_info->shadow_pad_size - start_offset,
                                   map_alignment) == 0);
 
-            memset(mem_info->shadow_copy, NoncoherentMemoryFillValue, 2 * mem_info->shadow_pad_size + size);
+            memset(mem_info->shadow_copy, NoncoherentMemoryFillValue, static_cast<size_t>(2 * mem_info->shadow_pad_size + size));
             *ppData = static_cast<char *>(mem_info->shadow_copy) + mem_info->shadow_pad_size;
         }
     }
@@ -5215,6 +5279,25 @@
     return skip_call;
 }
 
+static bool RetireFence(layer_data *dev_data, VkFence fence) {
+    auto pFence = getFenceNode(dev_data, fence);
+    if (pFence->signaler.first != VK_NULL_HANDLE) {
+        /* Fence signaller is a queue -- use this as proof that prior operations
+         * on that queue have completed.
+         */
+        return RetireWorkOnQueue(dev_data,
+                                 getQueueNode(dev_data, pFence->signaler.first),
+                                 pFence->signaler.second);
+    }
+    else {
+        /* Fence signaller is the WSI. We're not tracking what the WSI op
+         * actually /was/ in CV yet, but we need to mark the fence as retired.
+         */
+        pFence->state = FENCE_RETIRED;
+        return false;
+    }
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 WaitForFences(VkDevice device, uint32_t fenceCount, const VkFence *pFences, VkBool32 waitAll, uint64_t timeout) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
@@ -5228,19 +5311,14 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->WaitForFences(device, fenceCount, pFences, waitAll, timeout);
+    VkResult result = dev_data->dispatch_table.WaitForFences(device, fenceCount, pFences, waitAll, timeout);
 
     if (result == VK_SUCCESS) {
         lock.lock();
         // When we know that all fences are complete we can clean/remove their CBs
         if (waitAll || fenceCount == 1) {
             for (uint32_t i = 0; i < fenceCount; i++) {
-                auto pFence = getFenceNode(dev_data, pFences[i]);
-                if (pFence->signaler.first != VK_NULL_HANDLE) {
-                    skip_call |= RetireWorkOnQueue(dev_data,
-                                                   getQueueNode(dev_data, pFence->signaler.first),
-                                                   pFence->signaler.second);
-                }
+                skip_call |= RetireFence(dev_data, pFences[i]);
             }
         }
         // NOTE : Alternate case not handled here is when some fences have completed. In
@@ -5263,15 +5341,10 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->GetFenceStatus(device, fence);
+    VkResult result = dev_data->dispatch_table.GetFenceStatus(device, fence);
     lock.lock();
     if (result == VK_SUCCESS) {
-        auto pFence = getFenceNode(dev_data, fence);
-        if (pFence->signaler.first != VK_NULL_HANDLE) {
-            skip_call |= RetireWorkOnQueue(dev_data,
-                                           getQueueNode(dev_data, pFence->signaler.first),
-                                           pFence->signaler.second);
-        }
+        skip_call |= RetireFence(dev_data, fence);
     }
     lock.unlock();
     if (skip_call)
@@ -5282,7 +5355,7 @@
 VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex,
                                                             VkQueue *pQueue) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    dev_data->device_dispatch_table->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
+    dev_data->dispatch_table.GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
     std::lock_guard<std::mutex> lock(global_lock);
 
     // Add queue to tracking set only if it is new
@@ -5304,7 +5377,7 @@
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->QueueWaitIdle(queue);
+    VkResult result = dev_data->dispatch_table.QueueWaitIdle(queue);
     return result;
 }
 
@@ -5318,7 +5391,7 @@
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->DeviceWaitIdle(device);
+    VkResult result = dev_data->dispatch_table.DeviceWaitIdle(device);
     return result;
 }
 
@@ -5338,18 +5411,7 @@
     lock.unlock();
 
     if (!skip_call)
-        dev_data->device_dispatch_table->DestroyFence(device, fence, pAllocator);
-}
-
-// For given obj node, if it is use, flag a validation error and return callback result, else return false
-bool ValidateObjectNotInUse(const layer_data *dev_data, BASE_NODE *obj_node, VK_OBJECT obj_struct) {
-    bool skip = false;
-    if (obj_node->in_use.load()) {
-        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, obj_struct.type, obj_struct.handle, __LINE__,
-                        DRAWSTATE_OBJECT_INUSE, "DS", "Cannot delete %s 0x%" PRIx64 " that is currently in use by a command buffer.",
-                        object_type_to_string(obj_struct.type), obj_struct.handle);
-    }
-    return skip;
+        dev_data->dispatch_table.DestroyFence(device, fence, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -5360,30 +5422,44 @@
     auto sema_node = getSemaphoreNode(dev_data, semaphore);
     if (sema_node) {
         skip |= ValidateObjectNotInUse(dev_data, sema_node,
-                                       {reinterpret_cast<uint64_t &>(semaphore), VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT});
+                                       {reinterpret_cast<uint64_t &>(semaphore), VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT},
+                                       VALIDATION_ERROR_00199);
     }
     if (!skip) {
         dev_data->semaphoreMap.erase(semaphore);
         lock.unlock();
-        dev_data->device_dispatch_table->DestroySemaphore(device, semaphore, pAllocator);
+        dev_data->dispatch_table.DestroySemaphore(device, semaphore, pAllocator);
     }
 }
 
+static bool PreCallValidateDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE **event_state, VK_OBJECT *obj_struct) {
+    *event_state = getEventNode(dev_data, event);
+    *obj_struct = {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT};
+    if (dev_data->instance_data->disabled.destroy_event)
+        return false;
+    bool skip = false;
+    if (*event_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *event_state, *obj_struct, VALIDATION_ERROR_00213);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyEvent(layer_data *dev_data, VkEvent event, EVENT_STATE *event_state, VK_OBJECT obj_struct) {
+    invalidateCommandBuffers(event_state->cb_bindings, obj_struct);
+    dev_data->eventMap.erase(event);
+}
+
 VKAPI_ATTR void VKAPI_CALL DestroyEvent(VkDevice device, VkEvent event, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skip = false;
+    EVENT_STATE *event_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto event_node = getEventNode(dev_data, event);
-    if (event_node) {
-        VK_OBJECT obj_struct = {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT};
-        skip |= ValidateObjectNotInUse(dev_data, event_node, obj_struct);
-        // Any bound cmd buffers are now invalid
-        invalidateCommandBuffers(event_node->cb_bindings, obj_struct);
-    }
+    bool skip = PreCallValidateDestroyEvent(dev_data, event, &event_state, &obj_struct);
     if (!skip) {
-        dev_data->eventMap.erase(event);
         lock.unlock();
-        dev_data->device_dispatch_table->DestroyEvent(device, event, pAllocator);
+        dev_data->dispatch_table.DestroyEvent(device, event, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyEvent(dev_data, event, event_state, obj_struct);
     }
 }
 
@@ -5395,14 +5471,14 @@
     auto qp_node = getQueryPoolNode(dev_data, queryPool);
     if (qp_node) {
         VK_OBJECT obj_struct = {reinterpret_cast<uint64_t &>(queryPool), VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT};
-        skip |= ValidateObjectNotInUse(dev_data, qp_node, obj_struct);
+        skip |= ValidateObjectNotInUse(dev_data, qp_node, obj_struct, VALIDATION_ERROR_01012);
         // Any bound cmd buffers are now invalid
         invalidateCommandBuffers(qp_node->cb_bindings, obj_struct);
     }
     if (!skip) {
         dev_data->queryPoolMap.erase(queryPool);
         lock.unlock();
-        dev_data->device_dispatch_table->DestroyQueryPool(device, queryPool, pAllocator);
+        dev_data->dispatch_table.DestroyQueryPool(device, queryPool, pAllocator);
     }
 }
 
@@ -5475,8 +5551,7 @@
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    return dev_data->device_dispatch_table->GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride,
-                                                                flags);
+    return dev_data->dispatch_table.GetQueryPoolResults(device, queryPool, firstQuery, queryCount, dataSize, pData, stride, flags);
 }
 
 static bool validateIdleBuffer(const layer_data *my_data, VkBuffer buffer) {
@@ -5626,10 +5701,11 @@
     }
     erase_range->aliases.clear();
     mem_info->bound_ranges.erase(handle);
-    if (is_image)
+    if (is_image) {
         mem_info->bound_images.erase(handle);
-    else
+    } else {
         mem_info->bound_buffers.erase(handle);
+    }
 }
 
 static void RemoveBufferMemoryRange(uint64_t handle, DEVICE_MEM_INFO *mem_info) { RemoveMemoryRange(handle, mem_info, false); }
@@ -5647,58 +5723,99 @@
             // Any bound cmd buffers are now invalid
             invalidateCommandBuffers(buff_node->cb_bindings,
                                      {reinterpret_cast<uint64_t &>(buff_node->buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT});
-            auto mem_info = getMemObjInfo(dev_data, buff_node->mem);
+            auto mem_info = getMemObjInfo(dev_data, buff_node->binding.mem);
             if (mem_info) {
                 RemoveBufferMemoryRange(reinterpret_cast<uint64_t &>(buffer), mem_info);
             }
-            clear_object_binding(dev_data, reinterpret_cast<uint64_t &>(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+            ClearMemoryObjectBindings(dev_data, reinterpret_cast<uint64_t &>(buffer), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
             dev_data->bufferMap.erase(buff_node->buffer);
         }
         lock.unlock();
-        dev_data->device_dispatch_table->DestroyBuffer(device, buffer, pAllocator);
+        dev_data->dispatch_table.DestroyBuffer(device, buffer, pAllocator);
     }
 }
 
+static bool PreCallValidateDestroyBufferView(layer_data *dev_data, VkBufferView buffer_view, BUFFER_VIEW_STATE **buffer_view_state,
+                                             VK_OBJECT *obj_struct) {
+    *buffer_view_state = getBufferViewState(dev_data, buffer_view);
+    *obj_struct = {reinterpret_cast<uint64_t &>(buffer_view), VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT};
+    if (dev_data->instance_data->disabled.destroy_buffer_view)
+        return false;
+    bool skip = false;
+    if (*buffer_view_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *buffer_view_state, *obj_struct, VALIDATION_ERROR_00701);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyBufferView(layer_data *dev_data, VkBufferView buffer_view, BUFFER_VIEW_STATE *buffer_view_state,
+                                            VK_OBJECT obj_struct) {
+    // Any bound cmd buffers are now invalid
+    invalidateCommandBuffers(buffer_view_state->cb_bindings, obj_struct);
+    dev_data->bufferViewMap.erase(buffer_view);
+}
+
 VKAPI_ATTR void VKAPI_CALL
 DestroyBufferView(VkDevice device, VkBufferView bufferView, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
+    // Common data objects used pre & post call
+    BUFFER_VIEW_STATE *buffer_view_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto item = dev_data->bufferViewMap.find(bufferView);
-    if (item != dev_data->bufferViewMap.end()) {
-        dev_data->bufferViewMap.erase(item);
+    // Validate state before calling down chain, update common data if we'll be calling down chain
+    bool skip = PreCallValidateDestroyBufferView(dev_data, bufferView, &buffer_view_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyBufferView(device, bufferView, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyBufferView(dev_data, bufferView, buffer_view_state, obj_struct);
     }
-    lock.unlock();
-    dev_data->device_dispatch_table->DestroyBufferView(device, bufferView, pAllocator);
+}
+
+static bool PreCallValidateDestroyImage(layer_data *dev_data, VkImage image, IMAGE_STATE **image_state, VK_OBJECT *obj_struct) {
+    *image_state = getImageState(dev_data, image);
+    *obj_struct = {reinterpret_cast<uint64_t &>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT};
+    if (dev_data->instance_data->disabled.destroy_image)
+        return false;
+    bool skip = false;
+    if (*image_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *image_state, *obj_struct, VALIDATION_ERROR_00743);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyImage(layer_data *dev_data, VkImage image, IMAGE_STATE *image_state, VK_OBJECT obj_struct) {
+    invalidateCommandBuffers(image_state->cb_bindings, obj_struct);
+    // Clean up memory mapping, bindings and range references for image
+    auto mem_info = getMemObjInfo(dev_data, image_state->binding.mem);
+    if (mem_info) {
+        RemoveImageMemoryRange(obj_struct.handle, mem_info);
+    }
+    ClearMemoryObjectBindings(dev_data, obj_struct.handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+    // Remove image from imageMap
+    dev_data->imageMap.erase(image);
+
+    const auto &sub_entry = dev_data->imageSubresourceMap.find(image);
+    if (sub_entry != dev_data->imageSubresourceMap.end()) {
+        for (const auto &pair : sub_entry->second) {
+            dev_data->imageLayoutMap.erase(pair);
+        }
+        dev_data->imageSubresourceMap.erase(sub_entry);
+    }
 }
 
 VKAPI_ATTR void VKAPI_CALL DestroyImage(VkDevice device, VkImage image, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
+    IMAGE_STATE *image_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto img_node = getImageNode(dev_data, image);
-    if (img_node) {
-        // Any bound cmd buffers are now invalid
-        invalidateCommandBuffers(img_node->cb_bindings,
-                                 {reinterpret_cast<uint64_t &>(img_node->image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT});
-        // Clean up memory mapping, bindings and range references for image
-        auto mem_info = getMemObjInfo(dev_data, img_node->mem);
-        if (mem_info) {
-            RemoveImageMemoryRange(reinterpret_cast<uint64_t &>(image), mem_info);
-            clear_object_binding(dev_data, reinterpret_cast<uint64_t &>(image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
-        }
-        // Remove image from imageMap
-        dev_data->imageMap.erase(img_node->image);
+    bool skip = PreCallValidateDestroyImage(dev_data, image, &image_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyImage(device, image, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyImage(dev_data, image, image_state, obj_struct);
     }
-    const auto& subEntry = dev_data->imageSubresourceMap.find(image);
-    if (subEntry != dev_data->imageSubresourceMap.end()) {
-        for (const auto& pair : subEntry->second) {
-            dev_data->imageLayoutMap.erase(pair);
-        }
-        dev_data->imageSubresourceMap.erase(subEntry);
-    }
-    lock.unlock();
-    dev_data->device_dispatch_table->DestroyImage(device, image, pAllocator);
 }
 
 static bool ValidateMemoryTypes(const layer_data *dev_data, const DEVICE_MEM_INFO *mem_info, const uint32_t memory_type_bits,
@@ -5722,14 +5839,14 @@
     std::unique_lock<std::mutex> lock(global_lock);
     // Track objects tied to memory
     uint64_t buffer_handle = reinterpret_cast<uint64_t &>(buffer);
-    bool skip_call = set_mem_binding(dev_data, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory");
+    bool skip_call = SetMemBinding(dev_data, mem, buffer_handle, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, "vkBindBufferMemory");
     auto buffer_node = getBufferNode(dev_data, buffer);
     if (buffer_node) {
         VkMemoryRequirements memRequirements;
-        dev_data->device_dispatch_table->GetBufferMemoryRequirements(device, buffer, &memRequirements);
-        buffer_node->mem = mem;
-        buffer_node->memOffset = memoryOffset;
-        buffer_node->memSize = memRequirements.size;
+        dev_data->dispatch_table.GetBufferMemoryRequirements(device, buffer, &memRequirements);
+        buffer_node->binding.mem = mem;
+        buffer_node->binding.offset = memoryOffset;
+        buffer_node->binding.size = memRequirements.size;
 
         // Track and validate bound memory range information
         auto mem_info = getMemObjInfo(dev_data, mem);
@@ -5787,7 +5904,7 @@
     print_mem_list(dev_data);
     lock.unlock();
     if (!skip_call) {
-        result = dev_data->device_dispatch_table->BindBufferMemory(device, buffer, mem, memoryOffset);
+        result = dev_data->dispatch_table.BindBufferMemory(device, buffer, mem, memoryOffset);
     }
     return result;
 }
@@ -5797,7 +5914,7 @@
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     // TODO : What to track here?
     //   Could potentially save returned mem requirements and validate values passed into BindBufferMemory
-    my_data->device_dispatch_table->GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
+    my_data->dispatch_table.GetBufferMemoryRequirements(device, buffer, pMemoryRequirements);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -5805,14 +5922,43 @@
     layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     // TODO : What to track here?
     //   Could potentially save returned mem requirements and validate values passed into BindImageMemory
-    my_data->device_dispatch_table->GetImageMemoryRequirements(device, image, pMemoryRequirements);
+    my_data->dispatch_table.GetImageMemoryRequirements(device, image, pMemoryRequirements);
+}
+
+static bool PreCallValidateDestroyImageView(layer_data *dev_data, VkImageView image_view, IMAGE_VIEW_STATE **image_view_state,
+                                            VK_OBJECT *obj_struct) {
+    *image_view_state = getImageViewState(dev_data, image_view);
+    *obj_struct = {reinterpret_cast<uint64_t &>(image_view), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT};
+    if (dev_data->instance_data->disabled.destroy_image_view)
+        return false;
+    bool skip = false;
+    if (*image_view_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *image_view_state, *obj_struct, VALIDATION_ERROR_00776);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyImageView(layer_data *dev_data, VkImageView image_view, IMAGE_VIEW_STATE *image_view_state,
+                                           VK_OBJECT obj_struct) {
+    // Any bound cmd buffers are now invalid
+    invalidateCommandBuffers(image_view_state->cb_bindings, obj_struct);
+    dev_data->imageViewMap.erase(image_view);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyImageView(VkDevice device, VkImageView imageView, const VkAllocationCallbacks *pAllocator) {
-    // TODO : Clean up any internal data structures using this obj.
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyImageView(device, imageView, pAllocator);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    // Common data objects used pre & post call
+    IMAGE_VIEW_STATE *image_view_state = nullptr;
+    VK_OBJECT obj_struct;
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip = PreCallValidateDestroyImageView(dev_data, imageView, &image_view_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyImageView(device, imageView, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyImageView(dev_data, imageView, image_view_state, obj_struct);
+    }
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -5823,25 +5969,41 @@
     my_data->shaderModuleMap.erase(shaderModule);
     lock.unlock();
 
-    my_data->device_dispatch_table->DestroyShaderModule(device, shaderModule, pAllocator);
+    my_data->dispatch_table.DestroyShaderModule(device, shaderModule, pAllocator);
+}
+
+static bool PreCallValidateDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE **pipeline_state,
+                                           VK_OBJECT *obj_struct) {
+    *pipeline_state = getPipelineState(dev_data, pipeline);
+    *obj_struct = {reinterpret_cast<uint64_t &>(pipeline), VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT};
+    if (dev_data->instance_data->disabled.destroy_pipeline)
+        return false;
+    bool skip = false;
+    if (*pipeline_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *pipeline_state, *obj_struct, VALIDATION_ERROR_00555);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyPipeline(layer_data *dev_data, VkPipeline pipeline, PIPELINE_STATE *pipeline_state,
+                                          VK_OBJECT obj_struct) {
+    // Any bound cmd buffers are now invalid
+    invalidateCommandBuffers(pipeline_state->cb_bindings, obj_struct);
+    dev_data->pipelineMap.erase(pipeline);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skip = false;
+    PIPELINE_STATE *pipeline_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto pipe_node = getPipeline(dev_data, pipeline);
-    if (pipe_node) {
-        VK_OBJECT obj_struct = {reinterpret_cast<uint64_t &>(pipeline), VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT};
-        skip |= ValidateObjectNotInUse(dev_data, pipe_node, obj_struct);
-        // Any bound cmd buffers are now invalid
-        invalidateCommandBuffers(pipe_node->cb_bindings, obj_struct);
-    }
+    bool skip = PreCallValidateDestroyPipeline(dev_data, pipeline, &pipeline_state, &obj_struct);
     if (!skip) {
-        dev_data->pipelineMap.erase(pipeline);
         lock.unlock();
-        dev_data->device_dispatch_table->DestroyPipeline(device, pipeline, pAllocator);
+        dev_data->dispatch_table.DestroyPipeline(device, pipeline, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyPipeline(dev_data, pipeline, pipeline_state, obj_struct);
     }
 }
 
@@ -5852,25 +6014,42 @@
     dev_data->pipelineLayoutMap.erase(pipelineLayout);
     lock.unlock();
 
-    dev_data->device_dispatch_table->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
+    dev_data->dispatch_table.DestroyPipelineLayout(device, pipelineLayout, pAllocator);
+}
+
+static bool PreCallValidateDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE **sampler_state,
+                                          VK_OBJECT *obj_struct) {
+    *sampler_state = getSamplerState(dev_data, sampler);
+    *obj_struct = {reinterpret_cast<uint64_t &>(sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT};
+    if (dev_data->instance_data->disabled.destroy_sampler)
+        return false;
+    bool skip = false;
+    if (*sampler_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *sampler_state, *obj_struct, VALIDATION_ERROR_00837);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroySampler(layer_data *dev_data, VkSampler sampler, SAMPLER_STATE *sampler_state,
+                                         VK_OBJECT obj_struct) {
+    // Any bound cmd buffers are now invalid
+    if (sampler_state)
+        invalidateCommandBuffers(sampler_state->cb_bindings, obj_struct);
+    dev_data->samplerMap.erase(sampler);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroySampler(VkDevice device, VkSampler sampler, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skip = false;
+    SAMPLER_STATE *sampler_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto sampler_node = getSamplerNode(dev_data, sampler);
-    if (sampler_node) {
-        VK_OBJECT obj_struct = {reinterpret_cast<uint64_t &>(sampler), VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT};
-        skip |= ValidateObjectNotInUse(dev_data, sampler_node, obj_struct);
-        // Any bound cmd buffers are now invalid
-        invalidateCommandBuffers(sampler_node->cb_bindings, obj_struct);
-    }
+    bool skip = PreCallValidateDestroySampler(dev_data, sampler, &sampler_state, &obj_struct);
     if (!skip) {
-        dev_data->samplerMap.erase(sampler);
         lock.unlock();
-        dev_data->device_dispatch_table->DestroySampler(device, sampler, pAllocator);
+        dev_data->dispatch_table.DestroySampler(device, sampler, pAllocator);
+        lock.lock();
+        PostCallRecordDestroySampler(dev_data, sampler, sampler_state, obj_struct);
     }
 }
 
@@ -5878,41 +6057,75 @@
 DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, const VkAllocationCallbacks *pAllocator) {
     // TODO : Clean up any internal data structures using this obj.
     get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
+        ->dispatch_table.DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
+}
+
+static bool PreCallValidateDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool pool,
+                                                 DESCRIPTOR_POOL_STATE **desc_pool_state, VK_OBJECT *obj_struct) {
+    *desc_pool_state = getDescriptorPoolState(dev_data, pool);
+    *obj_struct = {reinterpret_cast<uint64_t &>(pool), VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT};
+    if (dev_data->instance_data->disabled.destroy_descriptor_pool)
+        return false;
+    bool skip = false;
+    if (*desc_pool_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *desc_pool_state, *obj_struct, VALIDATION_ERROR_00901);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyDescriptorPool(layer_data *dev_data, VkDescriptorPool descriptorPool,
+                                                DESCRIPTOR_POOL_STATE *desc_pool_state, VK_OBJECT obj_struct) {
+    // Any bound cmd buffers are now invalid
+    invalidateCommandBuffers(desc_pool_state->cb_bindings, obj_struct);
+    // Free sets that were in this pool
+    for (auto ds : desc_pool_state->sets) {
+        freeDescriptorSet(dev_data, ds);
+    }
+    dev_data->descriptorPoolMap.erase(descriptorPool);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, const VkAllocationCallbacks *pAllocator) {
-    // TODO : Clean up any internal data structures using this obj.
-    get_my_data_ptr(get_dispatch_key(device), layer_data_map)
-        ->device_dispatch_table->DestroyDescriptorPool(device, descriptorPool, pAllocator);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    DESCRIPTOR_POOL_STATE *desc_pool_state = nullptr;
+    VK_OBJECT obj_struct;
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip = PreCallValidateDestroyDescriptorPool(dev_data, descriptorPool, &desc_pool_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyDescriptorPool(device, descriptorPool, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyDescriptorPool(dev_data, descriptorPool, desc_pool_state, obj_struct);
+    }
 }
 // Verify cmdBuffer in given cb_node is not in global in-flight set, and return skip_call result
 //  If this is a secondary command buffer, then make sure its primary is also in-flight
 //  If primary is not in-flight, then remove secondary from global in-flight set
 // This function is only valid at a point when cmdBuffer is being reset or freed
-static bool checkCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action) {
+static bool checkCommandBufferInFlight(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const char *action,
+                                       UNIQUE_VALIDATION_ERROR_CODE error_code) {
     bool skip_call = false;
     if (dev_data->globalInFlightCmdBuffers.count(cb_node->commandBuffer)) {
         // Primary CB or secondary where primary is also in-flight is an error
         if ((cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_SECONDARY) ||
             (dev_data->globalInFlightCmdBuffers.count(cb_node->primaryCommandBuffer))) {
-            skip_call |= log_msg(
-                dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                reinterpret_cast<const uint64_t &>(cb_node->commandBuffer), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER_RESET, "DS",
-                "Attempt to %s command buffer (0x%" PRIxLEAST64 ") which is in use.", action,
-                reinterpret_cast<const uint64_t &>(cb_node->commandBuffer));
+            skip_call |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                        reinterpret_cast<const uint64_t &>(cb_node->commandBuffer), __LINE__, error_code, "DS",
+                        "Attempt to %s command buffer (0x%" PRIxLEAST64 ") which is in use. %s", action,
+                        reinterpret_cast<const uint64_t &>(cb_node->commandBuffer), validation_error_map[error_code]);
         }
     }
     return skip_call;
 }
 
 // Iterate over all cmdBuffers in given commandPool and verify that each is not in use
-static bool checkCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool, const char *action) {
+static bool checkCommandBuffersInFlight(layer_data *dev_data, COMMAND_POOL_NODE *pPool, const char *action,
+                                        UNIQUE_VALIDATION_ERROR_CODE error_code) {
     bool skip_call = false;
     for (auto cmd_buffer : pPool->commandBuffers) {
         if (dev_data->globalInFlightCmdBuffers.count(cmd_buffer)) {
-            skip_call |= checkCommandBufferInFlight(dev_data, getCBNode(dev_data, cmd_buffer), action);
+            skip_call |= checkCommandBufferInFlight(dev_data, getCBNode(dev_data, cmd_buffer), action, error_code);
         }
     }
     return skip_call;
@@ -5934,7 +6147,7 @@
         auto cb_node = getCBNode(dev_data, pCommandBuffers[i]);
         // Delete CB information structure, and remove from commandBufferMap
         if (cb_node) {
-            skip_call |= checkCommandBufferInFlight(dev_data, cb_node, "free");
+            skip_call |= checkCommandBufferInFlight(dev_data, cb_node, "free", VALIDATION_ERROR_00096);
         }
     }
 
@@ -5959,7 +6172,7 @@
     printCBList(dev_data);
     lock.unlock();
 
-    dev_data->device_dispatch_table->FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
+    dev_data->dispatch_table.FreeCommandBuffers(device, commandPool, commandBufferCount, pCommandBuffers);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateCommandPool(VkDevice device, const VkCommandPoolCreateInfo *pCreateInfo,
@@ -5967,7 +6180,7 @@
                                                  VkCommandPool *pCommandPool) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
-    VkResult result = dev_data->device_dispatch_table->CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
+    VkResult result = dev_data->dispatch_table.CreateCommandPool(device, pCreateInfo, pAllocator, pCommandPool);
 
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
@@ -5981,7 +6194,7 @@
                                                const VkAllocationCallbacks *pAllocator, VkQueryPool *pQueryPool) {
 
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
+    VkResult result = dev_data->dispatch_table.CreateQueryPool(device, pCreateInfo, pAllocator, pQueryPool);
     if (result == VK_SUCCESS) {
         std::lock_guard<std::mutex> lock(global_lock);
         QUERY_POOL_NODE *qp_node = &dev_data->queryPoolMap[*pQueryPool];
@@ -5990,21 +6203,22 @@
     return result;
 }
 
-// Destroy commandPool along with all of the commandBuffers allocated from that pool
-VKAPI_ATTR void VKAPI_CALL
-DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
-    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    bool skip_call = false;
-    std::unique_lock<std::mutex> lock(global_lock);
-    // Verify that command buffers in pool are complete (not in-flight)
-    auto pPool = getCommandPoolNode(dev_data, commandPool);
-    skip_call |= checkCommandBuffersInFlight(dev_data, pPool, "destroy command pool with");
+static bool PreCallValidateDestroyCommandPool(layer_data *dev_data, VkCommandPool pool, COMMAND_POOL_NODE **cp_state) {
+    *cp_state = getCommandPoolNode(dev_data, pool);
+    if (dev_data->instance_data->disabled.destroy_command_pool)
+        return false;
+    bool skip = false;
+    if (*cp_state) {
+        // Verify that command buffers in pool are complete (not in-flight)
+        skip |= checkCommandBuffersInFlight(dev_data, *cp_state, "destroy command pool with", VALIDATION_ERROR_00077);
+    }
+    return skip;
+}
 
-    if (skip_call)
-        return;
+static void PostCallRecordDestroyCommandPool(layer_data *dev_data, VkCommandPool pool, COMMAND_POOL_NODE *cp_state) {
     // Must remove cmdpool from cmdpoolmap, after removing all cmdbuffers in its list from the commandBufferMap
-    clearCommandBuffersInFlight(dev_data, pPool);
-    for (auto cb : pPool->commandBuffers) {
+    clearCommandBuffersInFlight(dev_data, cp_state);
+    for (auto cb : cp_state->commandBuffers) {
         clear_cmd_buf_and_mem_references(dev_data, cb);
         auto cb_node = getCBNode(dev_data, cb);
         // Remove references to this cb_node prior to delete
@@ -6013,17 +6227,28 @@
             removeCommandBufferBinding(dev_data, &obj, cb_node);
         }
         for (auto framebuffer : cb_node->framebuffers) {
-            auto fb_node = getFramebuffer(dev_data, framebuffer);
-            if (fb_node)
-                fb_node->cb_bindings.erase(cb_node);
+            auto fb_state = getFramebufferState(dev_data, framebuffer);
+            if (fb_state)
+                fb_state->cb_bindings.erase(cb_node);
         }
         dev_data->commandBufferMap.erase(cb); // Remove this command buffer
         delete cb_node;                       // delete CB info structure
     }
-    dev_data->commandPoolMap.erase(commandPool);
-    lock.unlock();
+    dev_data->commandPoolMap.erase(pool);
+}
 
-    dev_data->device_dispatch_table->DestroyCommandPool(device, commandPool, pAllocator);
+// Destroy commandPool along with all of the commandBuffers allocated from that pool
+VKAPI_ATTR void VKAPI_CALL DestroyCommandPool(VkDevice device, VkCommandPool commandPool, const VkAllocationCallbacks *pAllocator) {
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    COMMAND_POOL_NODE *cp_state = nullptr;
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip = PreCallValidateDestroyCommandPool(dev_data, commandPool, &cp_state);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyCommandPool(device, commandPool, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyCommandPool(dev_data, commandPool, cp_state);
+    }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
@@ -6033,13 +6258,13 @@
 
     std::unique_lock<std::mutex> lock(global_lock);
     auto pPool = getCommandPoolNode(dev_data, commandPool);
-    skip_call |= checkCommandBuffersInFlight(dev_data, pPool, "reset command pool with");
+    skip_call |= checkCommandBuffersInFlight(dev_data, pPool, "reset command pool with", VALIDATION_ERROR_00072);
     lock.unlock();
 
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->ResetCommandPool(device, commandPool, flags);
+    VkResult result = dev_data->dispatch_table.ResetCommandPool(device, commandPool, flags);
 
     // Reset all of the CBs allocated from this pool
     if (VK_SUCCESS == result) {
@@ -6070,7 +6295,7 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->ResetFences(device, fenceCount, pFences);
+    VkResult result = dev_data->dispatch_table.ResetFences(device, fenceCount, pFences);
 
     if (result == VK_SUCCESS) {
         lock.lock();
@@ -6094,35 +6319,83 @@
     }
 }
 
+static bool PreCallValidateDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer,
+                                              FRAMEBUFFER_STATE **framebuffer_state, VK_OBJECT *obj_struct) {
+    *framebuffer_state = getFramebufferState(dev_data, framebuffer);
+    *obj_struct = {reinterpret_cast<uint64_t &>(framebuffer), VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT};
+    if (dev_data->instance_data->disabled.destroy_framebuffer)
+        return false;
+    bool skip = false;
+    if (*framebuffer_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *framebuffer_state, *obj_struct, VALIDATION_ERROR_00422);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyFramebuffer(layer_data *dev_data, VkFramebuffer framebuffer, FRAMEBUFFER_STATE *framebuffer_state,
+                                             VK_OBJECT obj_struct) {
+    invalidateCommandBuffers(framebuffer_state->cb_bindings, obj_struct);
+    dev_data->frameBufferMap.erase(framebuffer);
+}
+
 VKAPI_ATTR void VKAPI_CALL
 DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    FRAMEBUFFER_STATE *framebuffer_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto fb_node = getFramebuffer(dev_data, framebuffer);
-    if (fb_node) {
-        invalidateCommandBuffers(fb_node->cb_bindings,
-                                 {reinterpret_cast<uint64_t &>(fb_node->framebuffer), VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT});
-        dev_data->frameBufferMap.erase(fb_node->framebuffer);
+    bool skip = PreCallValidateDestroyFramebuffer(dev_data, framebuffer, &framebuffer_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyFramebuffer(device, framebuffer, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyFramebuffer(dev_data, framebuffer, framebuffer_state, obj_struct);
     }
-    lock.unlock();
-    dev_data->device_dispatch_table->DestroyFramebuffer(device, framebuffer, pAllocator);
+}
+
+static bool PreCallValidateDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE **rp_state,
+                                             VK_OBJECT *obj_struct) {
+    *rp_state = getRenderPassState(dev_data, render_pass);
+    *obj_struct = {reinterpret_cast<uint64_t &>(render_pass), VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT};
+    if (dev_data->instance_data->disabled.destroy_renderpass)
+        return false;
+    bool skip = false;
+    if (*rp_state) {
+        skip |= ValidateObjectNotInUse(dev_data, *rp_state, *obj_struct, VALIDATION_ERROR_00393);
+    }
+    return skip;
+}
+
+static void PostCallRecordDestroyRenderPass(layer_data *dev_data, VkRenderPass render_pass, RENDER_PASS_STATE *rp_state,
+                                            VK_OBJECT obj_struct) {
+    invalidateCommandBuffers(rp_state->cb_bindings, obj_struct);
+    dev_data->renderPassMap.erase(render_pass);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyRenderPass(VkDevice device, VkRenderPass renderPass, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    RENDER_PASS_STATE *rp_state = nullptr;
+    VK_OBJECT obj_struct;
     std::unique_lock<std::mutex> lock(global_lock);
-    dev_data->renderPassMap.erase(renderPass);
-    // TODO: leaking all the guts of the renderpass node here!
-    lock.unlock();
-    dev_data->device_dispatch_table->DestroyRenderPass(device, renderPass, pAllocator);
+    bool skip = PreCallValidateDestroyRenderPass(dev_data, renderPass, &rp_state, &obj_struct);
+    if (!skip) {
+        lock.unlock();
+        dev_data->dispatch_table.DestroyRenderPass(device, renderPass, pAllocator);
+        lock.lock();
+        PostCallRecordDestroyRenderPass(dev_data, renderPass, rp_state, obj_struct);
+    }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateBuffer(VkDevice device, const VkBufferCreateInfo *pCreateInfo,
                                             const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
-    VkResult result = dev_data->device_dispatch_table->CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
+    // TODO: Add check for VALIDATION_ERROR_00658
+    // TODO: Add check for VALIDATION_ERROR_00666
+    // TODO: Add check for VALIDATION_ERROR_00667
+    // TODO: Add check for VALIDATION_ERROR_00668
+    // TODO: Add check for VALIDATION_ERROR_00669
+    VkResult result = dev_data->dispatch_table.CreateBuffer(device, pCreateInfo, pAllocator, pBuffer);
 
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
@@ -6155,10 +6428,10 @@
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->CreateBufferView(device, pCreateInfo, pAllocator, pView);
+    VkResult result = dev_data->dispatch_table.CreateBufferView(device, pCreateInfo, pAllocator, pView);
     if (VK_SUCCESS == result) {
         lock.lock();
-        dev_data->bufferViewMap[*pView] = unique_ptr<VkBufferViewCreateInfo>(new VkBufferViewCreateInfo(*pCreateInfo));
+        dev_data->bufferViewMap[*pView] = unique_ptr<BUFFER_VIEW_STATE>(new BUFFER_VIEW_STATE(*pView, pCreateInfo));
         lock.unlock();
     }
     return result;
@@ -6168,17 +6441,17 @@
                                            const VkAllocationCallbacks *pAllocator, VkImage *pImage) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
-    VkResult result = dev_data->device_dispatch_table->CreateImage(device, pCreateInfo, pAllocator, pImage);
+    VkResult result = dev_data->dispatch_table.CreateImage(device, pCreateInfo, pAllocator, pImage);
 
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
-        IMAGE_LAYOUT_NODE image_node;
-        image_node.layout = pCreateInfo->initialLayout;
-        image_node.format = pCreateInfo->format;
-        dev_data->imageMap.insert(std::make_pair(*pImage, unique_ptr<IMAGE_NODE>(new IMAGE_NODE(*pImage, pCreateInfo))));
+        IMAGE_LAYOUT_NODE image_state;
+        image_state.layout = pCreateInfo->initialLayout;
+        image_state.format = pCreateInfo->format;
+        dev_data->imageMap.insert(std::make_pair(*pImage, unique_ptr<IMAGE_STATE>(new IMAGE_STATE(*pImage, pCreateInfo))));
         ImageSubresourcePair subpair = {*pImage, false, VkImageSubresource()};
         dev_data->imageSubresourceMap[*pImage].push_back(subpair);
-        dev_data->imageLayoutMap[subpair] = image_node;
+        dev_data->imageLayoutMap[subpair] = image_state;
     }
     return result;
 }
@@ -6186,18 +6459,18 @@
 static void ResolveRemainingLevelsLayers(layer_data *dev_data, VkImageSubresourceRange *range, VkImage image) {
     /* expects global_lock to be held by caller */
 
-    auto image_node = getImageNode(dev_data, image);
-    if (image_node) {
+    auto image_state = getImageState(dev_data, image);
+    if (image_state) {
         /* If the caller used the special values VK_REMAINING_MIP_LEVELS and
          * VK_REMAINING_ARRAY_LAYERS, resolve them now in our internal state to
          * the actual values.
          */
         if (range->levelCount == VK_REMAINING_MIP_LEVELS) {
-            range->levelCount = image_node->createInfo.mipLevels - range->baseMipLevel;
+            range->levelCount = image_state->createInfo.mipLevels - range->baseMipLevel;
         }
 
         if (range->layerCount == VK_REMAINING_ARRAY_LAYERS) {
-            range->layerCount = image_node->createInfo.arrayLayers - range->baseArrayLayer;
+            range->layerCount = image_state->createInfo.arrayLayers - range->baseArrayLayer;
         }
     }
 }
@@ -6210,35 +6483,35 @@
 
     *levels = range.levelCount;
     *layers = range.layerCount;
-    auto image_node = getImageNode(dev_data, image);
-    if (image_node) {
+    auto image_state = getImageState(dev_data, image);
+    if (image_state) {
         if (range.levelCount == VK_REMAINING_MIP_LEVELS) {
-            *levels = image_node->createInfo.mipLevels - range.baseMipLevel;
+            *levels = image_state->createInfo.mipLevels - range.baseMipLevel;
         }
         if (range.layerCount == VK_REMAINING_ARRAY_LAYERS) {
-            *layers = image_node->createInfo.arrayLayers - range.baseArrayLayer;
+            *layers = image_state->createInfo.arrayLayers - range.baseArrayLayer;
         }
     }
 }
 
 static bool PreCallValidateCreateImageView(layer_data *dev_data, const VkImageViewCreateInfo *pCreateInfo) {
     bool skip_call = false;
-    IMAGE_NODE *image_node = getImageNode(dev_data, pCreateInfo->image);
-    if (image_node) {
+    IMAGE_STATE *image_state = getImageState(dev_data, pCreateInfo->image);
+    if (image_state) {
         skip_call |= ValidateImageUsageFlags(
-            dev_data, image_node, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
-                                      VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+            dev_data, image_state, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
+                                       VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
             false, "vkCreateImageView()",
             "VK_IMAGE_USAGE_[SAMPLED|STORAGE|COLOR_ATTACHMENT|DEPTH_STENCIL_ATTACHMENT|INPUT_ATTACHMENT]_BIT");
         // If this isn't a sparse image, it needs to have memory backing it at CreateImageView time
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, image_node, "vkCreateImageView()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCreateImageView()");
     }
     return skip_call;
 }
 
-static inline void PostCallRecordCreateImageView(layer_data *dev_data, const VkImageViewCreateInfo *pCreateInfo, VkImageView *pView) {
-    dev_data->imageViewMap[*pView] = unique_ptr<VkImageViewCreateInfo>(new VkImageViewCreateInfo(*pCreateInfo));
-    ResolveRemainingLevelsLayers(dev_data, &dev_data->imageViewMap[*pView].get()->subresourceRange, pCreateInfo->image);
+static inline void PostCallRecordCreateImageView(layer_data *dev_data, const VkImageViewCreateInfo *pCreateInfo, VkImageView view) {
+    dev_data->imageViewMap[view] = unique_ptr<IMAGE_VIEW_STATE>(new IMAGE_VIEW_STATE(view, pCreateInfo));
+    ResolveRemainingLevelsLayers(dev_data, &dev_data->imageViewMap[view].get()->create_info.subresourceRange, pCreateInfo->image);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateImageView(VkDevice device, const VkImageViewCreateInfo *pCreateInfo,
@@ -6249,10 +6522,10 @@
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->CreateImageView(device, pCreateInfo, pAllocator, pView);
+    VkResult result = dev_data->dispatch_table.CreateImageView(device, pCreateInfo, pAllocator, pView);
     if (VK_SUCCESS == result) {
         lock.lock();
-        PostCallRecordCreateImageView(dev_data, pCreateInfo, pView);
+        PostCallRecordCreateImageView(dev_data, pCreateInfo, *pView);
         lock.unlock();
     }
 
@@ -6262,7 +6535,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateFence(VkDevice device, const VkFenceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkFence *pFence) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateFence(device, pCreateInfo, pAllocator, pFence);
+    VkResult result = dev_data->dispatch_table.CreateFence(device, pCreateInfo, pAllocator, pFence);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         auto &fence_node = dev_data->fenceMap[*pFence];
@@ -6277,32 +6550,32 @@
 VKAPI_ATTR VkResult VKAPI_CALL CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo *pCreateInfo,
                                                    const VkAllocationCallbacks *pAllocator, VkPipelineCache *pPipelineCache) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
+    VkResult result = dev_data->dispatch_table.CreatePipelineCache(device, pCreateInfo, pAllocator, pPipelineCache);
     return result;
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache, const VkAllocationCallbacks *pAllocator) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    dev_data->device_dispatch_table->DestroyPipelineCache(device, pipelineCache, pAllocator);
+    dev_data->dispatch_table.DestroyPipelineCache(device, pipelineCache, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
 GetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache, size_t *pDataSize, void *pData) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
+    VkResult result = dev_data->dispatch_table.GetPipelineCacheData(device, pipelineCache, pDataSize, pData);
     return result;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
 MergePipelineCaches(VkDevice device, VkPipelineCache dstCache, uint32_t srcCacheCount, const VkPipelineCache *pSrcCaches) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
+    VkResult result = dev_data->dispatch_table.MergePipelineCaches(device, dstCache, srcCacheCount, pSrcCaches);
     return result;
 }
 
 // utility function to set collective state for pipeline
-void set_pipeline_state(PIPELINE_NODE *pPipe) {
+void set_pipeline_state(PIPELINE_STATE *pPipe) {
     // If any attachment used by this pipeline has blendEnable, set top-level blendEnable
     if (pPipe->graphicsPipelineCI.pColorBlendState) {
         for (size_t i = 0; i < pPipe->attachments.size(); ++i) {
@@ -6329,39 +6602,39 @@
     VkResult result = VK_SUCCESS;
     // TODO What to do with pipelineCache?
     // The order of operations here is a little convoluted but gets the job done
-    //  1. Pipeline create state is first shadowed into PIPELINE_NODE struct
+    //  1. Pipeline create state is first shadowed into PIPELINE_STATE struct
     //  2. Create state is then validated (which uses flags setup during shadowing)
     //  3. If everything looks good, we'll then create the pipeline and add NODE to pipelineMap
     bool skip_call = false;
     // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic
-    vector<PIPELINE_NODE *> pPipeNode(count);
+    vector<PIPELINE_STATE *> pPipeState(count);
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     uint32_t i = 0;
     std::unique_lock<std::mutex> lock(global_lock);
 
     for (i = 0; i < count; i++) {
-        pPipeNode[i] = new PIPELINE_NODE;
-        pPipeNode[i]->initGraphicsPipeline(&pCreateInfos[i]);
-        pPipeNode[i]->render_pass_ci.initialize(getRenderPass(dev_data, pCreateInfos[i].renderPass)->pCreateInfo);
-        pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
+        pPipeState[i] = new PIPELINE_STATE;
+        pPipeState[i]->initGraphicsPipeline(&pCreateInfos[i]);
+        pPipeState[i]->render_pass_ci.initialize(getRenderPassState(dev_data, pCreateInfos[i].renderPass)->createInfo.ptr());
+        pPipeState[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
 
-        skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode, i);
+        skip_call |= verifyPipelineCreateState(dev_data, device, pPipeState, i);
     }
 
     if (!skip_call) {
         lock.unlock();
-        result = dev_data->device_dispatch_table->CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
-                                                                          pPipelines);
+        result =
+            dev_data->dispatch_table.CreateGraphicsPipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
         lock.lock();
         for (i = 0; i < count; i++) {
-            pPipeNode[i]->pipeline = pPipelines[i];
-            dev_data->pipelineMap[pPipeNode[i]->pipeline] = pPipeNode[i];
+            pPipeState[i]->pipeline = pPipelines[i];
+            dev_data->pipelineMap[pPipeState[i]->pipeline] = pPipeState[i];
         }
         lock.unlock();
     } else {
         for (i = 0; i < count; i++) {
-            delete pPipeNode[i];
+            delete pPipeState[i];
         }
         lock.unlock();
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -6377,7 +6650,7 @@
     bool skip_call = false;
 
     // TODO : Improve this data struct w/ unique_ptrs so cleanup below is automatic
-    vector<PIPELINE_NODE *> pPipeNode(count);
+    vector<PIPELINE_STATE *> pPipeState(count);
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     uint32_t i = 0;
@@ -6386,31 +6659,31 @@
         // TODO: Verify compute stage bits
 
         // Create and initialize internal tracking data structure
-        pPipeNode[i] = new PIPELINE_NODE;
-        pPipeNode[i]->initComputePipeline(&pCreateInfos[i]);
-        pPipeNode[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
-        // memcpy(&pPipeNode[i]->computePipelineCI, (const void *)&pCreateInfos[i], sizeof(VkComputePipelineCreateInfo));
+        pPipeState[i] = new PIPELINE_STATE;
+        pPipeState[i]->initComputePipeline(&pCreateInfos[i]);
+        pPipeState[i]->pipeline_layout = *getPipelineLayout(dev_data, pCreateInfos[i].layout);
+        // memcpy(&pPipeState[i]->computePipelineCI, (const void *)&pCreateInfos[i], sizeof(VkComputePipelineCreateInfo));
 
         // TODO: Add Compute Pipeline Verification
-        skip_call |= !validate_compute_pipeline(dev_data->report_data, pPipeNode[i], &dev_data->phys_dev_properties.features,
+        skip_call |= !validate_compute_pipeline(dev_data->report_data, pPipeState[i], &dev_data->enabled_features,
                                                 dev_data->shaderModuleMap);
-        // skip_call |= verifyPipelineCreateState(dev_data, device, pPipeNode[i]);
+        // skip_call |= verifyPipelineCreateState(dev_data, device, pPipeState[i]);
     }
 
     if (!skip_call) {
         lock.unlock();
-        result = dev_data->device_dispatch_table->CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator,
-                                                                         pPipelines);
+        result =
+            dev_data->dispatch_table.CreateComputePipelines(device, pipelineCache, count, pCreateInfos, pAllocator, pPipelines);
         lock.lock();
         for (i = 0; i < count; i++) {
-            pPipeNode[i]->pipeline = pPipelines[i];
-            dev_data->pipelineMap[pPipeNode[i]->pipeline] = pPipeNode[i];
+            pPipeState[i]->pipeline = pPipelines[i];
+            dev_data->pipelineMap[pPipeState[i]->pipeline] = pPipeState[i];
         }
         lock.unlock();
     } else {
         for (i = 0; i < count; i++) {
             // Clean up any locally allocated data structures
-            delete pPipeNode[i];
+            delete pPipeState[i];
         }
         lock.unlock();
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -6421,24 +6694,40 @@
 VKAPI_ATTR VkResult VKAPI_CALL CreateSampler(VkDevice device, const VkSamplerCreateInfo *pCreateInfo,
                                              const VkAllocationCallbacks *pAllocator, VkSampler *pSampler) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateSampler(device, pCreateInfo, pAllocator, pSampler);
+    VkResult result = dev_data->dispatch_table.CreateSampler(device, pCreateInfo, pAllocator, pSampler);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
-        dev_data->samplerMap[*pSampler] = unique_ptr<SAMPLER_NODE>(new SAMPLER_NODE(pSampler, pCreateInfo));
+        dev_data->samplerMap[*pSampler] = unique_ptr<SAMPLER_STATE>(new SAMPLER_STATE(pSampler, pCreateInfo));
     }
     return result;
 }
 
+static bool PreCallValidateCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info) {
+    if (dev_data->instance_data->disabled.create_descriptor_set_layout)
+        return false;
+    return cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(dev_data->report_data, create_info);
+}
+
+static void PostCallRecordCreateDescriptorSetLayout(layer_data *dev_data, const VkDescriptorSetLayoutCreateInfo *create_info,
+                                                    VkDescriptorSetLayout set_layout) {
+    // TODO: Convert this to unique_ptr to avoid leaks
+    dev_data->descriptorSetLayoutMap[set_layout] = new cvdescriptorset::DescriptorSetLayout(create_info, set_layout);
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo *pCreateInfo,
                           const VkAllocationCallbacks *pAllocator, VkDescriptorSetLayout *pSetLayout) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
-    if (VK_SUCCESS == result) {
-        // TODOSC : Capture layout bindings set
-        std::lock_guard<std::mutex> lock(global_lock);
-        dev_data->descriptorSetLayoutMap[*pSetLayout] =
-            new cvdescriptorset::DescriptorSetLayout(dev_data->report_data, pCreateInfo, *pSetLayout);
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    std::unique_lock<std::mutex> lock(global_lock);
+    bool skip = PreCallValidateCreateDescriptorSetLayout(dev_data, pCreateInfo);
+    if (!skip) {
+        lock.unlock();
+        result = dev_data->dispatch_table.CreateDescriptorSetLayout(device, pCreateInfo, pAllocator, pSetLayout);
+        if (VK_SUCCESS == result) {
+            lock.lock();
+            PostCallRecordCreateDescriptorSetLayout(dev_data, pCreateInfo, *pSetLayout);
+        }
     }
     return result;
 }
@@ -6447,18 +6736,21 @@
 // Note that the index argument is optional and only used by CreatePipelineLayout.
 static bool validatePushConstantRange(const layer_data *dev_data, const uint32_t offset, const uint32_t size,
                                       const char *caller_name, uint32_t index = 0) {
+    if (dev_data->instance_data->disabled.push_constant_range)
+        return false;
     uint32_t const maxPushConstantsSize = dev_data->phys_dev_properties.properties.limits.maxPushConstantsSize;
     bool skip_call = false;
     // Check that offset + size don't exceed the max.
     // Prevent arithetic overflow here by avoiding addition and testing in this order.
+    // TODO : This check combines VALIDATION_ERROR_00877 & 880, need to break out separately
     if ((offset >= maxPushConstantsSize) || (size > maxPushConstantsSize - offset)) {
         // This is a pain just to adapt the log message to the caller, but better to sort it out only when there is a problem.
         if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) {
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                        DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with offset %u and size %u that "
-                                                              "exceeds this device's maxPushConstantSize of %u.",
-                        caller_name, index, offset, size, maxPushConstantsSize);
+                        VALIDATION_ERROR_00877, "DS", "%s call has push constants index %u with offset %u and size %u that "
+                                                      "exceeds this device's maxPushConstantSize of %u. %s",
+                        caller_name, index, offset, size, maxPushConstantsSize, validation_error_map[VALIDATION_ERROR_00877]);
         } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                  DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants with offset %u and size %u that "
@@ -6470,13 +6762,13 @@
         }
     }
     // size needs to be non-zero and a multiple of 4.
+    // TODO : This check combines VALIDATION_ERROR_00878 & 879, need to break out separately
     if ((size == 0) || ((size & 0x3) != 0)) {
         if (0 == strcmp(caller_name, "vkCreatePipelineLayout()")) {
-            skip_call |=
-                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                        DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "%s call has push constants index %u with "
-                                                              "size %u. Size must be greater than zero and a multiple of 4.",
-                        caller_name, index, size);
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                                 VALIDATION_ERROR_00878, "DS", "%s call has push constants index %u with "
+                                                               "size %u. Size must be greater than zero and a multiple of 4. %s",
+                                 caller_name, index, size, validation_error_map[VALIDATION_ERROR_00878]);
         } else if (0 == strcmp(caller_name, "vkCmdPushConstants()")) {
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -6512,8 +6804,9 @@
                                                     const VkAllocationCallbacks *pAllocator, VkPipelineLayout *pPipelineLayout) {
     bool skip_call = false;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    // TODO : Add checks for VALIDATION_ERRORS 865-871
     // Push Constant Range checks
-    uint32_t i = 0;
+    uint32_t i, j;
     for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
         skip_call |= validatePushConstantRange(dev_data, pCreateInfo->pPushConstantRanges[i].offset,
                                                pCreateInfo->pPushConstantRanges[i].size, "vkCreatePipelineLayout()", i);
@@ -6522,30 +6815,28 @@
                                  DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has no stageFlags set.");
         }
     }
+    if (skip_call)
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+
     // Each range has been validated.  Now check for overlap between ranges (if they are good).
-    if (!skip_call) {
-        uint32_t i, j;
-        for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
-            for (j = i + 1; j < pCreateInfo->pushConstantRangeCount; ++j) {
-                const uint32_t minA = pCreateInfo->pPushConstantRanges[i].offset;
-                const uint32_t maxA = minA + pCreateInfo->pPushConstantRanges[i].size;
-                const uint32_t minB = pCreateInfo->pPushConstantRanges[j].offset;
-                const uint32_t maxB = minB + pCreateInfo->pPushConstantRanges[j].size;
-                if ((minA <= minB && maxA > minB) || (minB <= minA && maxB > minA)) {
-                    skip_call |=
-                        log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has push constants with "
-                                                                      "overlapping ranges: %u:[%u, %u), %u:[%u, %u)",
-                                i, minA, maxA, j, minB, maxB);
-                }
+    // There's no explicit Valid Usage language against this, so issue a warning instead of an error.
+    for (i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
+        for (j = i + 1; j < pCreateInfo->pushConstantRangeCount; ++j) {
+            const uint32_t minA = pCreateInfo->pPushConstantRanges[i].offset;
+            const uint32_t maxA = minA + pCreateInfo->pPushConstantRanges[i].size;
+            const uint32_t minB = pCreateInfo->pPushConstantRanges[j].offset;
+            const uint32_t maxB = minB + pCreateInfo->pPushConstantRanges[j].size;
+            if ((minA <= minB && maxA > minB) || (minB <= minA && maxB > minA)) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_PUSH_CONSTANTS_ERROR, "DS", "vkCreatePipelineLayout() call has push constants with "
+                                                                  "overlapping ranges: %u:[%u, %u), %u:[%u, %u)",
+                            i, minA, maxA, j, minB, maxB);
             }
         }
     }
 
-    if (skip_call)
-        return VK_ERROR_VALIDATION_FAILED_EXT;
-
-    VkResult result = dev_data->device_dispatch_table->CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
+    VkResult result = dev_data->dispatch_table.CreatePipelineLayout(device, pCreateInfo, pAllocator, pPipelineLayout);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         PIPELINE_LAYOUT_NODE &plNode = dev_data->pipelineLayoutMap[*pPipelineLayout];
@@ -6566,18 +6857,17 @@
 CreateDescriptorPool(VkDevice device, const VkDescriptorPoolCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
                      VkDescriptorPool *pDescriptorPool) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
+    VkResult result = dev_data->dispatch_table.CreateDescriptorPool(device, pCreateInfo, pAllocator, pDescriptorPool);
     if (VK_SUCCESS == result) {
-        // Insert this pool into Global Pool LL at head
         if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
                     (uint64_t)*pDescriptorPool, __LINE__, DRAWSTATE_OUT_OF_MEMORY, "DS", "Created Descriptor Pool 0x%" PRIxLEAST64,
                     (uint64_t)*pDescriptorPool))
             return VK_ERROR_VALIDATION_FAILED_EXT;
-        DESCRIPTOR_POOL_NODE *pNewNode = new DESCRIPTOR_POOL_NODE(*pDescriptorPool, pCreateInfo);
+        DESCRIPTOR_POOL_STATE *pNewNode = new DESCRIPTOR_POOL_STATE(*pDescriptorPool, pCreateInfo);
         if (NULL == pNewNode) {
             if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
                         (uint64_t)*pDescriptorPool, __LINE__, DRAWSTATE_OUT_OF_MEMORY, "DS",
-                        "Out of memory while attempting to allocate DESCRIPTOR_POOL_NODE in vkCreateDescriptorPool()"))
+                        "Out of memory while attempting to allocate DESCRIPTOR_POOL_STATE in vkCreateDescriptorPool()"))
                 return VK_ERROR_VALIDATION_FAILED_EXT;
         } else {
             std::lock_guard<std::mutex> lock(global_lock);
@@ -6591,8 +6881,9 @@
 
 VKAPI_ATTR VkResult VKAPI_CALL
 ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags flags) {
+    // TODO : Add checks for VALIDATION_ERROR_00928
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->ResetDescriptorPool(device, descriptorPool, flags);
+    VkResult result = dev_data->dispatch_table.ResetDescriptorPool(device, descriptorPool, flags);
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
         clearDescriptorPool(dev_data, device, descriptorPool, flags);
@@ -6604,6 +6895,8 @@
 // as well as DescriptorSetLayout ptrs used for later update.
 static bool PreCallValidateAllocateDescriptorSets(layer_data *dev_data, const VkDescriptorSetAllocateInfo *pAllocateInfo,
                                                   cvdescriptorset::AllocateDescriptorSetsData *common_data) {
+    if (dev_data->instance_data->disabled.allocate_descriptor_sets)
+        return false;
     // All state checks for AllocateDescriptorSets is done in single function
     return cvdescriptorset::ValidateAllocateDescriptorSets(dev_data->report_data, pAllocateInfo, dev_data, common_data);
 }
@@ -6627,7 +6920,7 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
+    VkResult result = dev_data->dispatch_table.AllocateDescriptorSets(device, pAllocateInfo, pDescriptorSets);
 
     if (VK_SUCCESS == result) {
         lock.lock();
@@ -6639,25 +6932,28 @@
 // Verify state before freeing DescriptorSets
 static bool PreCallValidateFreeDescriptorSets(const layer_data *dev_data, VkDescriptorPool pool, uint32_t count,
                                               const VkDescriptorSet *descriptor_sets) {
+    if (dev_data->instance_data->disabled.free_descriptor_sets)
+        return false;
     bool skip_call = false;
     // First make sure sets being destroyed are not currently in-use
     for (uint32_t i = 0; i < count; ++i)
         skip_call |= validateIdleDescriptorSet(dev_data, descriptor_sets[i], "vkFreeDescriptorSets");
 
-    DESCRIPTOR_POOL_NODE *pool_node = getPoolNode(dev_data, pool);
-    if (pool_node && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_node->createInfo.flags)) {
+    DESCRIPTOR_POOL_STATE *pool_state = getDescriptorPoolState(dev_data, pool);
+    if (pool_state && !(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT & pool_state->createInfo.flags)) {
         // Can't Free from a NON_FREE pool
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                             reinterpret_cast<uint64_t &>(pool), __LINE__, DRAWSTATE_CANT_FREE_FROM_NON_FREE_POOL, "DS",
+                             reinterpret_cast<uint64_t &>(pool), __LINE__, VALIDATION_ERROR_00922, "DS",
                              "It is invalid to call vkFreeDescriptorSets() with a pool created without setting "
-                             "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT.");
+                             "VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT. %s",
+                             validation_error_map[VALIDATION_ERROR_00922]);
     }
     return skip_call;
 }
 // Sets have been removed from the pool so update underlying state
 static void PostCallRecordFreeDescriptorSets(layer_data *dev_data, VkDescriptorPool pool, uint32_t count,
                                              const VkDescriptorSet *descriptor_sets) {
-    DESCRIPTOR_POOL_NODE *pool_state = getPoolNode(dev_data, pool);
+    DESCRIPTOR_POOL_STATE *pool_state = getDescriptorPoolState(dev_data, pool);
     // Update available descriptor sets in pool
     pool_state->availableSets += count;
 
@@ -6685,7 +6981,7 @@
 
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
+    VkResult result = dev_data->dispatch_table.FreeDescriptorSets(device, descriptorPool, count, pDescriptorSets);
     if (VK_SUCCESS == result) {
         lock.lock();
         PostCallRecordFreeDescriptorSets(dev_data, descriptorPool, count, pDescriptorSets);
@@ -6700,6 +6996,8 @@
 static bool PreCallValidateUpdateDescriptorSets(layer_data *dev_data, uint32_t descriptorWriteCount,
                                                 const VkWriteDescriptorSet *pDescriptorWrites, uint32_t descriptorCopyCount,
                                                 const VkCopyDescriptorSet *pDescriptorCopies) {
+    if (dev_data->instance_data->disabled.update_descriptor_sets)
+        return false;
     // First thing to do is perform map look-ups.
     // NOTE : UpdateDescriptorSets is somewhat unique in that it's operating on a number of DescriptorSets
     //  so we can't just do a single map look-up up-front, but do them individually in functions below
@@ -6728,8 +7026,8 @@
                                                          pDescriptorCopies);
     lock.unlock();
     if (!skip_call) {
-        dev_data->device_dispatch_table->UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
-                                                              pDescriptorCopies);
+        dev_data->dispatch_table.UpdateDescriptorSets(device, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
+                                                      pDescriptorCopies);
         lock.lock();
         // Since UpdateDescriptorSets() is void, nothing to check prior to updating state
         PostCallRecordUpdateDescriptorSets(dev_data, descriptorWriteCount, pDescriptorWrites, descriptorCopyCount,
@@ -6740,7 +7038,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL
 AllocateCommandBuffers(VkDevice device, const VkCommandBufferAllocateInfo *pCreateInfo, VkCommandBuffer *pCommandBuffer) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
+    VkResult result = dev_data->dispatch_table.AllocateCommandBuffers(device, pCreateInfo, pCommandBuffer);
     if (VK_SUCCESS == result) {
         std::unique_lock<std::mutex> lock(global_lock);
         auto pPool = getCommandPoolNode(dev_data, pCreateInfo->commandPool);
@@ -6763,6 +7061,25 @@
     return result;
 }
 
+// Add bindings between the given cmd buffer & framebuffer and the framebuffer's children
+static void AddFramebufferBinding(layer_data *dev_data, GLOBAL_CB_NODE *cb_state, FRAMEBUFFER_STATE *fb_state) {
+    addCommandBufferBinding(&fb_state->cb_bindings,
+                            {reinterpret_cast<uint64_t &>(fb_state->framebuffer), VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT},
+                            cb_state);
+    for (auto attachment : fb_state->attachments) {
+        auto view_state = attachment.view_state;
+        if (view_state) {
+            AddCommandBufferBindingImageView(dev_data, cb_state, view_state);
+        }
+        auto rp_state = getRenderPassState(dev_data, fb_state->createInfo.renderPass);
+        if (rp_state) {
+            addCommandBufferBinding(
+                &rp_state->cb_bindings,
+                {reinterpret_cast<uint64_t &>(rp_state->renderPass), VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT}, cb_state);
+        }
+    }
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL
 BeginCommandBuffer(VkCommandBuffer commandBuffer, const VkCommandBufferBeginInfo *pBeginInfo) {
     bool skip_call = false;
@@ -6776,8 +7093,8 @@
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, MEMTRACK_RESET_CB_WHILE_IN_FLIGHT, "MEM",
-                        "Calling vkBeginCommandBuffer() on active CB 0x%p before it has completed. "
-                        "You must check CB fence before this call.",
+                        "Calling vkBeginCommandBuffer() on active command buffer 0x%p before it has completed. "
+                        "You must check command buffer fence before this call.",
                         commandBuffer);
         }
         clear_cmd_buf_and_mem_references(dev_data, cb_node);
@@ -6808,11 +7125,11 @@
                             reinterpret_cast<void *>(commandBuffer));
                     } else {
                         string errorString = "";
-                        auto framebuffer = getFramebuffer(dev_data, pInfo->framebuffer);
+                        auto framebuffer = getFramebufferState(dev_data, pInfo->framebuffer);
                         if (framebuffer) {
                             if ((framebuffer->createInfo.renderPass != pInfo->renderPass) &&
                                 !verify_renderpass_compatibility(dev_data, framebuffer->renderPassCreateInfo.ptr(),
-                                                                 getRenderPass(dev_data, pInfo->renderPass)->pCreateInfo,
+                                                                 getRenderPassState(dev_data, pInfo->renderPass)->createInfo.ptr(),
                                                                  errorString)) {
                                 // renderPass that framebuffer was created with must be compatible with local renderPass
                                 skip_call |= log_msg(
@@ -6826,21 +7143,13 @@
                                     reinterpret_cast<const uint64_t &>(pInfo->framebuffer),
                                     reinterpret_cast<uint64_t &>(framebuffer->createInfo.renderPass), errorString.c_str());
                             }
-                            // Connect this framebuffer to this cmdBuffer
-                            framebuffer->cb_bindings.insert(cb_node);
-                            for (auto attach : framebuffer->attachments) {
-                                auto img_node = getImageNode(dev_data, attach.image);
-                                if (img_node) {
-                                    addCommandBufferBinding(&img_node->cb_bindings, {reinterpret_cast<uint64_t &>(attach.image),
-                                                                                     VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT},
-                                                            cb_node);
-                                }
-                            }
+                            // Connect this framebuffer and its children to this cmdBuffer
+                            AddFramebufferBinding(dev_data, cb_node, framebuffer);
                         }
                     }
                 }
                 if ((pInfo->occlusionQueryEnable == VK_FALSE ||
-                     dev_data->phys_dev_properties.features.occlusionQueryPrecise == VK_FALSE) &&
+                     dev_data->enabled_features.occlusionQueryPrecise == VK_FALSE) &&
                     (pInfo->queryFlags & VK_QUERY_CONTROL_PRECISE_BIT)) {
                     skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t>(commandBuffer),
@@ -6852,15 +7161,15 @@
                 }
             }
             if (pInfo && pInfo->renderPass != VK_NULL_HANDLE) {
-                auto renderPass = getRenderPass(dev_data, pInfo->renderPass);
+                auto renderPass = getRenderPassState(dev_data, pInfo->renderPass);
                 if (renderPass) {
-                    if (pInfo->subpass >= renderPass->pCreateInfo->subpassCount) {
+                    if (pInfo->subpass >= renderPass->createInfo.subpassCount) {
                         skip_call |= log_msg(
                             dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             (uint64_t)commandBuffer, __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
                             "vkBeginCommandBuffer(): Secondary Command Buffers (0x%p) must has a subpass index (%d) "
                             "that is less than the number of subpasses (%d).",
-                            (void *)commandBuffer, pInfo->subpass, renderPass->pCreateInfo->subpassCount);
+                            (void *)commandBuffer, pInfo->subpass, renderPass->createInfo.subpassCount);
                     }
                 }
             }
@@ -6869,7 +7178,7 @@
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)commandBuffer, __LINE__, DRAWSTATE_BEGIN_CB_INVALID_STATE, "DS",
-                        "vkBeginCommandBuffer(): Cannot call Begin on CB (0x%" PRIxLEAST64
+                        "vkBeginCommandBuffer(): Cannot call Begin on command buffer (0x%" PRIxLEAST64
                         ") in the RECORDING state. Must first call vkEndCommandBuffer().",
                         (uint64_t)commandBuffer);
         } else if (CB_RECORDED == cb_node->state || (CB_INVALID == cb_node->state && CMD_END == cb_node->cmds.back().type)) {
@@ -6895,7 +7204,7 @@
             // If we are a secondary command-buffer and inheriting.  Update the items we should inherit.
             if ((cb_node->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) &&
                 (cb_node->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
-                cb_node->activeRenderPass = getRenderPass(dev_data, cb_node->beginInfo.pInheritanceInfo->renderPass);
+                cb_node->activeRenderPass = getRenderPassState(dev_data, cb_node->beginInfo.pInheritanceInfo->renderPass);
                 cb_node->activeSubpass = cb_node->beginInfo.pInheritanceInfo->subpass;
                 cb_node->framebuffers.insert(cb_node->beginInfo.pInheritanceInfo->framebuffer);
             }
@@ -6903,13 +7212,14 @@
     } else {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                              (uint64_t)commandBuffer, __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
-                             "In vkBeginCommandBuffer() and unable to find CommandBuffer Node for CB 0x%p!", (void *)commandBuffer);
+                             "In vkBeginCommandBuffer() and unable to find CommandBuffer Node for command buffer 0x%p!",
+                             (void *)commandBuffer);
     }
     lock.unlock();
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
     }
-    VkResult result = dev_data->device_dispatch_table->BeginCommandBuffer(commandBuffer, pBeginInfo);
+    VkResult result = dev_data->dispatch_table.BeginCommandBuffer(commandBuffer, pBeginInfo);
 
     return result;
 }
@@ -6936,7 +7246,7 @@
     }
     if (!skip_call) {
         lock.unlock();
-        result = dev_data->device_dispatch_table->EndCommandBuffer(commandBuffer);
+        result = dev_data->dispatch_table.EndCommandBuffer(commandBuffer);
         lock.lock();
         if (VK_SUCCESS == result) {
             pCB->state = CB_RECORDED;
@@ -6966,11 +7276,11 @@
                              ") that does NOT have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT bit set.",
                              (uint64_t)commandBuffer, (uint64_t)cmdPool);
     }
-    skip_call |= checkCommandBufferInFlight(dev_data, pCB, "reset");
+    skip_call |= checkCommandBufferInFlight(dev_data, pCB, "reset", VALIDATION_ERROR_00092);
     lock.unlock();
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
-    VkResult result = dev_data->device_dispatch_table->ResetCommandBuffer(commandBuffer, flags);
+    VkResult result = dev_data->dispatch_table.ResetCommandBuffer(commandBuffer, flags);
     if (VK_SUCCESS == result) {
         lock.lock();
         dev_data->globalInFlightCmdBuffers.erase(commandBuffer);
@@ -6996,9 +7306,9 @@
                         (uint64_t)pipeline, (uint64_t)pCB->activeRenderPass->renderPass);
         }
 
-        PIPELINE_NODE *pPN = getPipeline(dev_data, pipeline);
+        PIPELINE_STATE *pPN = getPipelineState(dev_data, pipeline);
         if (pPN) {
-            pCB->lastBound[pipelineBindPoint].pipeline_node = pPN;
+            pCB->lastBound[pipelineBindPoint].pipeline_state = pPN;
             set_cb_pso_status(pCB, pPN);
             set_pipeline_state(pPN);
         } else {
@@ -7006,12 +7316,12 @@
                                  (uint64_t)pipeline, __LINE__, DRAWSTATE_INVALID_PIPELINE, "DS",
                                  "Attempt to bind Pipeline 0x%" PRIxLEAST64 " that doesn't exist!", (uint64_t)(pipeline));
         }
-        addCommandBufferBinding(&getPipeline(dev_data, pipeline)->cb_bindings,
+        addCommandBufferBinding(&getPipelineState(dev_data, pipeline)->cb_bindings,
                                 {reinterpret_cast<uint64_t &>(pipeline), VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT}, pCB);
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
+        dev_data->dispatch_table.CmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7022,12 +7332,11 @@
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
         skip_call |= addCmd(dev_data, pCB, CMD_SETVIEWPORTSTATE, "vkCmdSetViewport()");
-        pCB->status |= CBSTATUS_VIEWPORT_SET;
         pCB->viewportMask |= ((1u<<viewportCount) - 1u) << firstViewport;
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
+        dev_data->dispatch_table.CmdSetViewport(commandBuffer, firstViewport, viewportCount, pViewports);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7038,12 +7347,11 @@
     GLOBAL_CB_NODE *pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
         skip_call |= addCmd(dev_data, pCB, CMD_SETSCISSORSTATE, "vkCmdSetScissor()");
-        pCB->status |= CBSTATUS_SCISSOR_SET;
         pCB->scissorMask |= ((1u<<scissorCount) - 1u) << firstScissor;
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
+        dev_data->dispatch_table.CmdSetScissor(commandBuffer, firstScissor, scissorCount, pScissors);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) {
@@ -7055,7 +7363,7 @@
         skip_call |= addCmd(dev_data, pCB, CMD_SETLINEWIDTHSTATE, "vkCmdSetLineWidth()");
         pCB->status |= CBSTATUS_LINE_WIDTH_SET;
 
-        PIPELINE_NODE *pPipeTrav = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline_node;
+        PIPELINE_STATE *pPipeTrav = pCB->lastBound[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline_state;
         if (pPipeTrav != NULL && !isDynamic(pPipeTrav, VK_DYNAMIC_STATE_LINE_WIDTH)) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
                                  reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, DRAWSTATE_INVALID_SET, "DS",
@@ -7067,7 +7375,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetLineWidth(commandBuffer, lineWidth);
+        dev_data->dispatch_table.CmdSetLineWidth(commandBuffer, lineWidth);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7082,8 +7390,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp,
-                                                         depthBiasSlopeFactor);
+        dev_data->dispatch_table.CmdSetDepthBias(commandBuffer, depthBiasConstantFactor, depthBiasClamp, depthBiasSlopeFactor);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdSetBlendConstants(VkCommandBuffer commandBuffer, const float blendConstants[4]) {
@@ -7097,7 +7404,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetBlendConstants(commandBuffer, blendConstants);
+        dev_data->dispatch_table.CmdSetBlendConstants(commandBuffer, blendConstants);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7112,7 +7419,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
+        dev_data->dispatch_table.CmdSetDepthBounds(commandBuffer, minDepthBounds, maxDepthBounds);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7127,7 +7434,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
+        dev_data->dispatch_table.CmdSetStencilCompareMask(commandBuffer, faceMask, compareMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7142,7 +7449,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
+        dev_data->dispatch_table.CmdSetStencilWriteMask(commandBuffer, faceMask, writeMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7157,7 +7464,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetStencilReference(commandBuffer, faceMask, reference);
+        dev_data->dispatch_table.CmdSetStencilReference(commandBuffer, faceMask, reference);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7187,13 +7494,13 @@
                     pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i + firstSet] = pSet;
                     skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
                                          VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
-                                         DRAWSTATE_NONE, "DS", "DS 0x%" PRIxLEAST64 " bound on pipeline %s",
+                                         DRAWSTATE_NONE, "DS", "Descriptor Set 0x%" PRIxLEAST64 " bound on pipeline %s",
                                          (uint64_t)pDescriptorSets[i], string_VkPipelineBindPoint(pipelineBindPoint));
                     if (!pSet->IsUpdated() && (pSet->GetTotalDescriptorCount() != 0)) {
                         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
                                              VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
                                              DRAWSTATE_DESCRIPTOR_SET_NOT_UPDATED, "DS",
-                                             "DS 0x%" PRIxLEAST64
+                                             "Descriptor Set 0x%" PRIxLEAST64
                                              " bound but it was never updated. You may want to either update it or not bind it.",
                                              (uint64_t)pDescriptorSets[i]);
                     }
@@ -7269,7 +7576,8 @@
                 } else {
                     skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, (uint64_t)pDescriptorSets[i], __LINE__,
-                                         DRAWSTATE_INVALID_SET, "DS", "Attempt to bind DS 0x%" PRIxLEAST64 " that doesn't exist!",
+                                         DRAWSTATE_INVALID_SET, "DS", "Attempt to bind descriptor set 0x%" PRIxLEAST64
+                                         " that doesn't exist!",
                                          (uint64_t)pDescriptorSets[i]);
                 }
                 skip_call |= addCmd(dev_data, pCB, CMD_BINDDESCRIPTORSETS, "vkCmdBindDescriptorSets()");
@@ -7283,7 +7591,7 @@
                                 dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                 VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
                                 (uint64_t)pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i], __LINE__, DRAWSTATE_NONE, "DS",
-                                "DescriptorSetDS 0x%" PRIxLEAST64
+                                "DescriptorSet 0x%" PRIxLEAST64
                                 " previously bound as set #%u was disturbed by newly bound pipelineLayout (0x%" PRIxLEAST64 ")",
                                 (uint64_t)pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i], i, (uint64_t)layout);
                             pCB->lastBound[pipelineBindPoint].boundDescriptorSets[i] = VK_NULL_HANDLE;
@@ -7298,7 +7606,7 @@
                         skip_call |=
                             log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                     VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, reinterpret_cast<uint64_t &>(old_set), __LINE__,
-                                    DRAWSTATE_NONE, "DS", "DescriptorSetDS 0x%" PRIxLEAST64
+                                    DRAWSTATE_NONE, "DS", "DescriptorSet 0x%" PRIxLEAST64
                                                           " previously bound as set #%u is incompatible with set 0x%" PRIxLEAST64
                                                           " newly bound as set #%u so set #%u and any subsequent sets were "
                                                           "disturbed by newly bound pipelineLayout (0x%" PRIxLEAST64 ")",
@@ -7324,8 +7632,8 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
-                                                               pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
+        dev_data->dispatch_table.CmdBindDescriptorSets(commandBuffer, pipelineBindPoint, layout, firstSet, setCount,
+                                                       pDescriptorSets, dynamicOffsetCount, pDynamicOffsets);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7368,7 +7676,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
+        dev_data->dispatch_table.CmdBindIndexBuffer(commandBuffer, buffer, offset, indexType);
 }
 
 void updateResourceTracking(GLOBAL_CB_NODE *pCB, uint32_t firstBinding, uint32_t bindingCount, const VkBuffer *pBuffers) {
@@ -7409,7 +7717,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
+        dev_data->dispatch_table.CmdBindVertexBuffers(commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets);
 }
 
 /* expects global_lock to be held by caller */
@@ -7417,14 +7725,14 @@
     bool skip_call = false;
 
     for (auto imageView : pCB->updateImages) {
-        auto iv_data = getImageViewData(dev_data, imageView);
-        if (!iv_data)
+        auto view_state = getImageViewState(dev_data, imageView);
+        if (!view_state)
             continue;
 
-        auto img_node = getImageNode(dev_data, iv_data->image);
-        assert(img_node);
+        auto image_state = getImageState(dev_data, view_state->create_info.image);
+        assert(image_state);
         std::function<bool()> function = [=]() {
-            SetImageMemoryValid(dev_data, img_node, true);
+            SetImageMemoryValid(dev_data, image_state, true);
             return false;
         };
         pCB->validate_functions.push_back(function);
@@ -7455,7 +7763,8 @@
         // TODO : Need to pass commandBuffer as srcObj here
         skip_call |=
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
-                    __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDraw() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW]++);
+                    __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDraw() call 0x%" PRIx64 ", reporting descriptor set state:",
+                    g_drawCount[DRAW]++);
         skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
         if (!skip_call) {
             updateResourceTrackingOnDraw(pCB);
@@ -7464,7 +7773,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
+        dev_data->dispatch_table.CmdDraw(commandBuffer, vertexCount, instanceCount, firstVertex, firstInstance);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
@@ -7482,7 +7791,8 @@
         // TODO : Need to pass commandBuffer as srcObj here
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
                              VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
-                             "vkCmdDrawIndexed() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDEXED]++);
+                             "vkCmdDrawIndexed() call 0x%" PRIx64 ", reporting descriptor set state:",
+                             g_drawCount[DRAW_INDEXED]++);
         skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
         if (!skip_call) {
             updateResourceTrackingOnDraw(pCB);
@@ -7491,8 +7801,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset,
-                                                        firstInstance);
+        dev_data->dispatch_table.CmdDrawIndexed(commandBuffer, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7513,7 +7822,8 @@
         // TODO : Need to pass commandBuffer as srcObj here
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT,
                              VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, __LINE__, DRAWSTATE_NONE, "DS",
-                             "vkCmdDrawIndirect() call 0x%" PRIx64 ", reporting DS state:", g_drawCount[DRAW_INDIRECT]++);
+                             "vkCmdDrawIndirect() call 0x%" PRIx64 ", reporting descriptor set state:",
+                             g_drawCount[DRAW_INDIRECT]++);
         skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
         if (!skip_call) {
             updateResourceTrackingOnDraw(cb_node);
@@ -7524,7 +7834,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
+        dev_data->dispatch_table.CmdDrawIndirect(commandBuffer, buffer, offset, count, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7546,7 +7856,7 @@
         // TODO : Need to pass commandBuffer as srcObj here
         skip_call |=
             log_msg(dev_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0,
-                    __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDrawIndexedIndirect() call 0x%" PRIx64 ", reporting DS state:",
+                    __LINE__, DRAWSTATE_NONE, "DS", "vkCmdDrawIndexedIndirect() call 0x%" PRIx64 ", reporting descriptor set state:",
                     g_drawCount[DRAW_INDEXED_INDIRECT]++);
         skip_call |= synchAndPrintDSConfig(dev_data, commandBuffer);
         if (!skip_call) {
@@ -7558,7 +7868,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
+        dev_data->dispatch_table.CmdDrawIndexedIndirect(commandBuffer, buffer, offset, count, stride);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdDispatch(VkCommandBuffer commandBuffer, uint32_t x, uint32_t y, uint32_t z) {
@@ -7574,7 +7884,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDispatch(commandBuffer, x, y, z);
+        dev_data->dispatch_table.CmdDispatch(commandBuffer, x, y, z);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -7596,7 +7906,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdDispatchIndirect(commandBuffer, buffer, offset);
+        dev_data->dispatch_table.CmdDispatchIndirect(commandBuffer, buffer, offset);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer,
@@ -7638,7 +7948,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
+        dev_data->dispatch_table.CmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, regionCount, pRegions);
 }
 
 static bool VerifySourceImageLayout(layer_data *dev_data, GLOBAL_CB_NODE *cb_node, VkImage srcImage,
@@ -7665,8 +7975,8 @@
     if (srcImageLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
         if (srcImageLayout == VK_IMAGE_LAYOUT_GENERAL) {
             // TODO : Can we deal with image node from the top of call tree and avoid map look-up here?
-            auto image_node = getImageNode(dev_data, srcImage);
-            if (image_node->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
+            auto image_state = getImageState(dev_data, srcImage);
+            if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
                 // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
                 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                      (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
@@ -7704,8 +8014,8 @@
     }
     if (destImageLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
         if (destImageLayout == VK_IMAGE_LAYOUT_GENERAL) {
-            auto image_node = getImageNode(dev_data, destImage);
-            if (image_node->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
+            auto image_state = getImageState(dev_data, destImage);
+            if (image_state->createInfo.tiling != VK_IMAGE_TILING_LINEAR) {
                 // LAYOUT_GENERAL is allowed, but may not be performance optimal, flag as perf warning.
                 skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
                                      (VkDebugReportObjectTypeEXT)0, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
@@ -7721,112 +8031,184 @@
     return skip_call;
 }
 
-// Test elements of a VkExtent3D structure against alignment constraints contained in another VkExtent3D structure
-static inline bool IsExtentAligned(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkExtent3D *extent,
-                                   VkExtent3D *granularity) {
-    bool valid = true;
+// Test if two VkExtent3D structs are equivalent
+static inline bool IsExtentEqual(const VkExtent3D *extent, const VkExtent3D *other_extent) {
+    bool result = true;
+    if ((extent->width != other_extent->width) || (extent->height != other_extent->height) ||
+        (extent->depth != other_extent->depth)) {
+        result = false;
+    }
+    return result;
+}
+
+// Returns the image extent of a specific subresource.
+static inline VkExtent3D GetImageSubresourceExtent(const IMAGE_STATE *img, const VkImageSubresourceLayers *subresource) {
+    const uint32_t mip = subresource->mipLevel;
+    VkExtent3D extent = img->createInfo.extent;
+    extent.width = std::max(1U, extent.width >> mip);
+    extent.height = std::max(1U, extent.height >> mip);
+    extent.depth = std::max(1U, extent.depth >> mip);
+    return extent;
+}
+
+// Test if the extent argument has all dimensions set to 0.
+static inline bool IsExtentZero(const VkExtent3D *extent) {
+    return ((extent->width == 0) && (extent->height == 0) && (extent->depth == 0));
+}
+
+// Returns the image transfer granularity for a specific image scaled by compressed block size if necessary.
+static inline VkExtent3D GetScaledItg(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const IMAGE_STATE *img) {
+    // Default to (0, 0, 0) granularity in case we can't find the real granularity for the physical device.
+    VkExtent3D granularity = { 0, 0, 0 };
     auto pPool = getCommandPoolNode(dev_data, cb_node->createInfo.commandPool);
     if (pPool) {
-        granularity = &dev_data->phys_dev_properties.queue_family_properties[pPool->queueFamilyIndex].minImageTransferGranularity;
-        if ((vk_safe_modulo(extent->depth, granularity->depth) != 0) || (vk_safe_modulo(extent->width, granularity->width) != 0) ||
-            (vk_safe_modulo(extent->height, granularity->height) != 0)) {
-            valid = false;
+        granularity = dev_data->phys_dev_properties.queue_family_properties[pPool->queueFamilyIndex].minImageTransferGranularity;
+        if (vk_format_is_compressed(img->createInfo.format)) {
+            auto block_size = vk_format_compressed_block_size(img->createInfo.format);
+            granularity.width *= block_size.width;
+            granularity.height *= block_size.height;
         }
     }
+    return granularity;
+}
+
+// Test elements of a VkExtent3D structure against alignment constraints contained in another VkExtent3D structure
+static inline bool IsExtentAligned(const VkExtent3D *extent, const VkExtent3D *granularity) {
+    bool valid = true;
+    if ((vk_safe_modulo(extent->depth, granularity->depth) != 0) || (vk_safe_modulo(extent->width, granularity->width) != 0) ||
+        (vk_safe_modulo(extent->height, granularity->height) != 0)) {
+        valid = false;
+    }
     return valid;
 }
 
 // Check elements of a VkOffset3D structure against a queue family's Image Transfer Granularity values
-static inline bool CheckItgOffset(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkOffset3D *offset, const uint32_t i,
-                                  const char *function, const char *member) {
+static inline bool CheckItgOffset(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkOffset3D *offset,
+                                  const VkExtent3D *granularity, const uint32_t i, const char *function, const char *member) {
     bool skip = false;
-    VkExtent3D granularity = {};
-    VkExtent3D extent = {};
-    extent.width = static_cast<uint32_t>(abs(offset->x));
-    extent.height = static_cast<uint32_t>(abs(offset->y));
-    extent.depth = static_cast<uint32_t>(abs(offset->z));
-    if (IsExtentAligned(dev_data, cb_node, &extent, &granularity) == false) {
-        skip |= log_msg(
-            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-            DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS", "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) must respect this command buffer's "
-                                                        "queue family image transfer granularity (w=%d, h=%d, d=%d).",
-            function, i, member, offset->x, offset->y, offset->z, granularity.width, granularity.height, granularity.depth);
+    VkExtent3D offset_extent = {};
+    offset_extent.width = static_cast<uint32_t>(abs(offset->x));
+    offset_extent.height = static_cast<uint32_t>(abs(offset->y));
+    offset_extent.depth = static_cast<uint32_t>(abs(offset->z));
+    if (IsExtentZero(granularity)) {
+        // If the queue family image transfer granularity is (0, 0, 0), then the offset must always be (0, 0, 0)
+        if (IsExtentZero(&offset_extent) == false) {
+            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
+                            "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) must be (x=0, y=0, z=0) "
+                            "when the command buffer's queue family image transfer granularity is (w=0, h=0, d=0).",
+                            function, i, member, offset->x, offset->y, offset->z);
+        }
+    } else {
+        // If the queue family image transfer granularity is not (0, 0, 0), then the offset dimensions must always be even
+        // integer multiples of the image transfer granularity.
+        if (IsExtentAligned(&offset_extent, granularity) == false) {
+            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
+                            "%s: pRegion[%d].%s (x=%d, y=%d, z=%d) dimensions must be even integer "
+                            "multiples of this command buffer's queue family image transfer granularity (w=%d, h=%d, d=%d).",
+                            function, i, member, offset->x, offset->y, offset->z, granularity->width, granularity->height,
+                            granularity->depth);
+        }
     }
     return skip;
 }
 
 // Check elements of a VkExtent3D structure against a queue family's Image Transfer Granularity values
-static inline bool CheckItgExtent(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkExtent3D *extent, const uint32_t i,
-                                  const char *function, const char *member) {
+static inline bool CheckItgExtent(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkExtent3D *extent,
+                                  const VkOffset3D *offset, const VkExtent3D *granularity, const VkExtent3D *subresource_extent,
+                                  const uint32_t i, const char *function, const char *member) {
     bool skip = false;
-    VkExtent3D granularity = {};
-    if (IsExtentAligned(dev_data, cb_node, extent, &granularity) == false) {
-        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+    if (IsExtentZero(granularity)) {
+        // If the queue family image transfer granularity is (0, 0, 0), then the extent must always match the image
+        // subresource extent.
+        if (IsExtentEqual(extent, subresource_extent) == false) {
+            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
+                            "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d) "
+                            "when the command buffer's queue family image transfer granularity is (w=0, h=0, d=0).",
+                            function, i, member, extent->width, extent->height, extent->depth, subresource_extent->width,
+                            subresource_extent->height, subresource_extent->depth);
+        }
+    } else {
+        // If the queue family image transfer granularity is not (0, 0, 0), then the extent dimensions must always be even
+        // integer multiples of the image transfer granularity or the offset + extent dimensions must always match the image
+        // subresource extent dimensions.
+        VkExtent3D offset_extent_sum = {};
+        offset_extent_sum.width = static_cast<uint32_t>(abs(offset->x)) + extent->width;
+        offset_extent_sum.height = static_cast<uint32_t>(abs(offset->y)) + extent->height;
+        offset_extent_sum.depth = static_cast<uint32_t>(abs(offset->z)) + extent->depth;
+        if ((IsExtentAligned(extent, granularity) == false) && (IsExtentEqual(&offset_extent_sum, subresource_extent) == false)) {
+            skip |=
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
-                        "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) must respect this command buffer's "
-                        "queue family image transfer granularity (w=%d, h=%d, z=%d).",
-                        function, i, member, extent->width, extent->height, extent->depth, granularity.width, granularity.height,
-                        granularity.depth);
+                        "%s: pRegion[%d].%s (w=%d, h=%d, d=%d) dimensions must be even integer multiples of this command buffer's "
+                        "queue family image transfer granularity (w=%d, h=%d, d=%d) or offset (x=%d, y=%d, z=%d) + "
+                        "extent (w=%d, h=%d, d=%d) must match the image subresource extents (w=%d, h=%d, d=%d).",
+                        function, i, member, extent->width, extent->height, extent->depth, granularity->width, granularity->height,
+                        granularity->depth, offset->x, offset->y, offset->z, extent->width, extent->height, extent->depth,
+                        subresource_extent->width, subresource_extent->height, subresource_extent->depth);
+        }
     }
     return skip;
 }
 
 // Check a uint32_t width or stride value against a queue family's Image Transfer Granularity width value
-static inline bool CheckItgInt(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const uint32_t value, const uint32_t i,
-                               const char *function, const char *member) {
+static inline bool CheckItgInt(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const uint32_t value,
+                               const uint32_t granularity, const uint32_t i, const char *function, const char *member) {
     bool skip = false;
-    VkExtent3D granularity = {};
-    VkExtent3D extent = {};
-    extent.width = value;
-    if (IsExtentAligned(dev_data, cb_node, &extent, &granularity) == false) {
+    if (vk_safe_modulo(value, granularity) != 0) {
         skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
-                        "%s: pRegion[%d].%s (%d) must respect this command buffer's queue family image transfer granularity %d).",
-                        function, i, member, extent.width, granularity.width);
+                        "%s: pRegion[%d].%s (%d) must be an even integer multiple of this command buffer's queue family image "
+                        "transfer granularity width (%d).",
+                        function, i, member, value, granularity);
     }
     return skip;
 }
 
 // Check a VkDeviceSize value against a queue family's Image Transfer Granularity width value
-static inline bool CheckItgSize(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkDeviceSize value, const uint32_t i,
-                                const char *function, const char *member) {
+static inline bool CheckItgSize(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node, const VkDeviceSize value,
+                                const uint32_t granularity, const uint32_t i, const char *function, const char *member) {
     bool skip = false;
-    VkExtent3D *granularity;
-    auto pPool = getCommandPoolNode(dev_data, cb_node->createInfo.commandPool);
-    if (pPool) {
-        granularity = &dev_data->phys_dev_properties.queue_family_properties[pPool->queueFamilyIndex].minImageTransferGranularity;
-        if (vk_safe_modulo(value, granularity->width) != 0) {
-            skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                            DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
-                            "%s: pRegion[%d].%s (%" PRIdLEAST64
-                            ") must respect this command buffer's queue family image transfer granularity %d).",
-                            function, i, member, value, granularity->width);
-        }
+    if (vk_safe_modulo(value, granularity) != 0) {
+        skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                        DRAWSTATE_IMAGE_TRANSFER_GRANULARITY, "DS",
+                        "%s: pRegion[%d].%s (%" PRIdLEAST64
+                        ") must be an even integer multiple of this command buffer's queue family image transfer "
+                        "granularity width (%d).",
+                        function, i, member, value, granularity);
     }
     return skip;
 }
 
 // Check valid usage Image Tranfer Granularity requirements for elements of a VkImageCopy structure
 static inline bool ValidateCopyImageTransferGranularityRequirements(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node,
-                                                                    const VkImageCopy *region, const uint32_t i,
-                                                                    const char *function) {
+                                                                    const IMAGE_STATE *img, const VkImageCopy *region,
+                                                                    const uint32_t i, const char *function) {
     bool skip = false;
-    skip |= CheckItgOffset(dev_data, cb_node, &region->srcOffset, i, function, "srcOffset");
-    skip |= CheckItgOffset(dev_data, cb_node, &region->dstOffset, i, function, "dstOffset");
-    skip |= CheckItgExtent(dev_data, cb_node, &region->extent, i, function, "extent");
+    VkExtent3D granularity = GetScaledItg(dev_data, cb_node, img);
+    skip |= CheckItgOffset(dev_data, cb_node, &region->srcOffset, &granularity, i, function, "srcOffset");
+    skip |= CheckItgOffset(dev_data, cb_node, &region->dstOffset, &granularity, i, function, "dstOffset");
+    VkExtent3D subresource_extent = GetImageSubresourceExtent(img, &region->dstSubresource);
+    skip |= CheckItgExtent(dev_data, cb_node, &region->extent, &region->dstOffset, &granularity, &subresource_extent, i, function,
+                           "extent");
     return skip;
 }
 
 // Check valid usage Image Tranfer Granularity requirements for elements of a VkBufferImageCopy structure
 static inline bool ValidateCopyBufferImageTransferGranularityRequirements(layer_data *dev_data, const GLOBAL_CB_NODE *cb_node,
-                                                                          const VkBufferImageCopy *region, const uint32_t i,
-                                                                          const char *function) {
+                                                                          const IMAGE_STATE *img, const VkBufferImageCopy *region,
+                                                                          const uint32_t i, const char *function) {
     bool skip = false;
-    skip |= CheckItgSize(dev_data, cb_node, region->bufferOffset, i, function, "bufferOffset");
-    skip |= CheckItgInt(dev_data, cb_node, region->bufferRowLength, i, function, "bufferRowLength");
-    skip |= CheckItgInt(dev_data, cb_node, region->bufferImageHeight, i, function, "bufferImageHeight");
-    skip |= CheckItgOffset(dev_data, cb_node, &region->imageOffset, i, function, "imageOffset");
-    skip |= CheckItgExtent(dev_data, cb_node, &region->imageExtent, i, function, "imageExtent");
+    VkExtent3D granularity = GetScaledItg(dev_data, cb_node, img);
+    skip |= CheckItgSize(dev_data, cb_node, region->bufferOffset, granularity.width, i, function, "bufferOffset");
+    skip |= CheckItgInt(dev_data, cb_node, region->bufferRowLength, granularity.width, i, function, "bufferRowLength");
+    skip |= CheckItgInt(dev_data, cb_node, region->bufferImageHeight, granularity.width, i, function, "bufferImageHeight");
+    skip |= CheckItgOffset(dev_data, cb_node, &region->imageOffset, &granularity, i, function, "imageOffset");
+    VkExtent3D subresource_extent = GetImageSubresourceExtent(img, &region->imageSubresource);
+    skip |= CheckItgExtent(dev_data, cb_node, &region->imageExtent, &region->imageOffset, &granularity, &subresource_extent, i,
+                           function, "imageExtent");
     return skip;
 }
 
@@ -7838,23 +8220,25 @@
     std::unique_lock<std::mutex> lock(global_lock);
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto src_img_node = getImageNode(dev_data, srcImage);
-    auto dst_img_node = getImageNode(dev_data, dstImage);
-    if (cb_node && src_img_node && dst_img_node) {
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdCopyImage()");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdCopyImage()");
+    auto src_image_state = getImageState(dev_data, srcImage);
+    auto dst_image_state = getImageState(dev_data, dstImage);
+    if (cb_node && src_image_state && dst_image_state) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_image_state, "vkCmdCopyImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_image_state, "vkCmdCopyImage()");
         // Update bindings between images and cmd buffer
-        AddCommandBufferBindingImage(dev_data, cb_node, src_img_node);
-        AddCommandBufferBindingImage(dev_data, cb_node, dst_img_node);
+        AddCommandBufferBindingImage(dev_data, cb_node, src_image_state);
+        AddCommandBufferBindingImage(dev_data, cb_node, dst_image_state);
         // Validate that SRC & DST images have correct usage flags set
-        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImage()",
+        skip_call |= ValidateImageUsageFlags(dev_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdCopyImage()",
                                              "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
-        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImage()",
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdCopyImage()",
                                              "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
-        std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(dev_data, src_img_node, "vkCmdCopyImage()"); };
+        std::function<bool()> function = [=]() {
+            return ValidateImageMemoryIsValid(dev_data, src_image_state, "vkCmdCopyImage()");
+        };
         cb_node->validate_functions.push_back(function);
         function = [=]() {
-            SetImageMemoryValid(dev_data, dst_img_node, true);
+            SetImageMemoryValid(dev_data, dst_image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -7864,27 +8248,28 @@
         for (uint32_t i = 0; i < regionCount; ++i) {
             skip_call |= VerifySourceImageLayout(dev_data, cb_node, srcImage, pRegions[i].srcSubresource, srcImageLayout);
             skip_call |= VerifyDestImageLayout(dev_data, cb_node, dstImage, pRegions[i].dstSubresource, dstImageLayout);
-            skip_call |= ValidateCopyImageTransferGranularityRequirements(dev_data, cb_node, &pRegions[i], i, "vkCmdCopyImage()");
+            skip_call |= ValidateCopyImageTransferGranularityRequirements(dev_data, cb_node, dst_image_state, &pRegions[i], i,
+                                                                          "vkCmdCopyImage()");
         }
     } else {
         assert(0);
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                                                      regionCount, pRegions);
+        dev_data->dispatch_table.CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
+                                              pRegions);
 }
 
 // Validate that an image's sampleCount matches the requirement for a specific API call
-static inline bool ValidateImageSampleCount(layer_data *dev_data, IMAGE_NODE *image_node, VkSampleCountFlagBits sample_count,
+static inline bool ValidateImageSampleCount(layer_data *dev_data, IMAGE_STATE *image_state, VkSampleCountFlagBits sample_count,
                                             const char *location) {
     bool skip = false;
-    if (image_node->createInfo.samples != sample_count) {
+    if (image_state->createInfo.samples != sample_count) {
         skip = log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
-                       reinterpret_cast<uint64_t &>(image_node->image), 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
+                       reinterpret_cast<uint64_t &>(image_state->image), 0, DRAWSTATE_NUM_SAMPLES_MISMATCH, "DS",
                        "%s for image 0x%" PRIxLEAST64 " was created with a sample count of %s but must be %s.", location,
-                       reinterpret_cast<uint64_t &>(image_node->image),
-                       string_VkSampleCountFlagBits(image_node->createInfo.samples), string_VkSampleCountFlagBits(sample_count));
+                       reinterpret_cast<uint64_t &>(image_state->image),
+                       string_VkSampleCountFlagBits(image_state->createInfo.samples), string_VkSampleCountFlagBits(sample_count));
     }
     return skip;
 }
@@ -7897,25 +8282,27 @@
     std::unique_lock<std::mutex> lock(global_lock);
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto src_img_node = getImageNode(dev_data, srcImage);
-    auto dst_img_node = getImageNode(dev_data, dstImage);
-    if (cb_node && src_img_node && dst_img_node) {
-        skip_call |= ValidateImageSampleCount(dev_data, src_img_node, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): srcImage");
-        skip_call |= ValidateImageSampleCount(dev_data, dst_img_node, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): dstImage");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdBlitImage()");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdBlitImage()");
+    auto src_image_state = getImageState(dev_data, srcImage);
+    auto dst_image_state = getImageState(dev_data, dstImage);
+    if (cb_node && src_image_state && dst_image_state) {
+        skip_call |= ValidateImageSampleCount(dev_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): srcImage");
+        skip_call |= ValidateImageSampleCount(dev_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdBlitImage(): dstImage");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_image_state, "vkCmdBlitImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_image_state, "vkCmdBlitImage()");
         // Update bindings between images and cmd buffer
-        AddCommandBufferBindingImage(dev_data, cb_node, src_img_node);
-        AddCommandBufferBindingImage(dev_data, cb_node, dst_img_node);
+        AddCommandBufferBindingImage(dev_data, cb_node, src_image_state);
+        AddCommandBufferBindingImage(dev_data, cb_node, dst_image_state);
         // Validate that SRC & DST images have correct usage flags set
-        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdBlitImage()",
+        skip_call |= ValidateImageUsageFlags(dev_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true, "vkCmdBlitImage()",
                                              "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
-        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdBlitImage()",
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true, "vkCmdBlitImage()",
                                              "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
-        std::function<bool()> function = [=]() { return ValidateImageMemoryIsValid(dev_data, src_img_node, "vkCmdBlitImage()"); };
+        std::function<bool()> function = [=]() {
+            return ValidateImageMemoryIsValid(dev_data, src_image_state, "vkCmdBlitImage()");
+        };
         cb_node->validate_functions.push_back(function);
         function = [=]() {
-            SetImageMemoryValid(dev_data, dst_img_node, true);
+            SetImageMemoryValid(dev_data, dst_image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -7927,8 +8314,8 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                                                      regionCount, pRegions, filter);
+        dev_data->dispatch_table.CmdBlitImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
+                                              pRegions, filter);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyBufferToImage(VkCommandBuffer commandBuffer, VkBuffer srcBuffer,
@@ -7940,19 +8327,20 @@
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
     auto src_buff_node = getBufferNode(dev_data, srcBuffer);
-    auto dst_img_node = getImageNode(dev_data, dstImage);
-    if (cb_node && src_buff_node && dst_img_node) {
-        skip_call |= ValidateImageSampleCount(dev_data, dst_img_node, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyBufferToImage(): dstImage");
+    auto dst_image_state = getImageState(dev_data, dstImage);
+    if (cb_node && src_buff_node && dst_image_state) {
+        skip_call |=
+            ValidateImageSampleCount(dev_data, dst_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyBufferToImage(): dstImage");
         skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, src_buff_node, "vkCmdCopyBufferToImage()");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdCopyBufferToImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_image_state, "vkCmdCopyBufferToImage()");
         AddCommandBufferBindingBuffer(dev_data, cb_node, src_buff_node);
-        AddCommandBufferBindingImage(dev_data, cb_node, dst_img_node);
+        AddCommandBufferBindingImage(dev_data, cb_node, dst_image_state);
         skip_call |= ValidateBufferUsageFlags(dev_data, src_buff_node, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, true,
                                               "vkCmdCopyBufferToImage()", "VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
-        skip_call |= ValidateImageUsageFlags(dev_data, dst_img_node, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
+        skip_call |= ValidateImageUsageFlags(dev_data, dst_image_state, VK_IMAGE_USAGE_TRANSFER_DST_BIT, true,
                                              "vkCmdCopyBufferToImage()", "VK_IMAGE_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            SetImageMemoryValid(dev_data, dst_img_node, true);
+            SetImageMemoryValid(dev_data, dst_image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -7963,16 +8351,15 @@
         skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyBufferToImage()");
         for (uint32_t i = 0; i < regionCount; ++i) {
             skip_call |= VerifyDestImageLayout(dev_data, cb_node, dstImage, pRegions[i].imageSubresource, dstImageLayout);
-            skip_call |=
-                ValidateCopyBufferImageTransferGranularityRequirements(dev_data, cb_node, &pRegions[i], i, "vkCmdCopyBufferToImage()");
+            skip_call |= ValidateCopyBufferImageTransferGranularityRequirements(dev_data, cb_node, dst_image_state, &pRegions[i], i,
+                                                                                "vkCmdCopyBufferToImage()");
         }
     } else {
         assert(0);
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount,
-                                                              pRegions);
+        dev_data->dispatch_table.CmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, dstImageLayout, regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, VkImage srcImage,
@@ -7983,22 +8370,23 @@
     std::unique_lock<std::mutex> lock(global_lock);
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto src_img_node = getImageNode(dev_data, srcImage);
+    auto src_image_state = getImageState(dev_data, srcImage);
     auto dst_buff_node = getBufferNode(dev_data, dstBuffer);
-    if (cb_node && src_img_node && dst_buff_node) {
-        skip_call |= ValidateImageSampleCount(dev_data, src_img_node, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyImageToBuffer(): srcImage");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdCopyImageToBuffer()");
+    if (cb_node && src_image_state && dst_buff_node) {
+        skip_call |=
+            ValidateImageSampleCount(dev_data, src_image_state, VK_SAMPLE_COUNT_1_BIT, "vkCmdCopyImageToBuffer(): srcImage");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_image_state, "vkCmdCopyImageToBuffer()");
         skip_call |= ValidateMemoryIsBoundToBuffer(dev_data, dst_buff_node, "vkCmdCopyImageToBuffer()");
         // Update bindings between buffer/image and cmd buffer
-        AddCommandBufferBindingImage(dev_data, cb_node, src_img_node);
+        AddCommandBufferBindingImage(dev_data, cb_node, src_image_state);
         AddCommandBufferBindingBuffer(dev_data, cb_node, dst_buff_node);
         // Validate that SRC image & DST buffer have correct usage flags set
-        skip_call |= ValidateImageUsageFlags(dev_data, src_img_node, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
+        skip_call |= ValidateImageUsageFlags(dev_data, src_image_state, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, true,
                                              "vkCmdCopyImageToBuffer()", "VK_IMAGE_USAGE_TRANSFER_SRC_BIT");
         skip_call |= ValidateBufferUsageFlags(dev_data, dst_buff_node, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true,
                                               "vkCmdCopyImageToBuffer()", "VK_BUFFER_USAGE_TRANSFER_DST_BIT");
         std::function<bool()> function = [=]() {
-            return ValidateImageMemoryIsValid(dev_data, src_img_node, "vkCmdCopyImageToBuffer()");
+            return ValidateImageMemoryIsValid(dev_data, src_image_state, "vkCmdCopyImageToBuffer()");
         };
         cb_node->validate_functions.push_back(function);
         function = [=]() {
@@ -8011,16 +8399,15 @@
         skip_call |= insideRenderPass(dev_data, cb_node, "vkCmdCopyImageToBuffer()");
         for (uint32_t i = 0; i < regionCount; ++i) {
             skip_call |= VerifySourceImageLayout(dev_data, cb_node, srcImage, pRegions[i].imageSubresource, srcImageLayout);
-            skip_call |=
-                ValidateCopyBufferImageTransferGranularityRequirements(dev_data, cb_node, &pRegions[i], i, "CmdCopyImageToBuffer");
+            skip_call |= ValidateCopyBufferImageTransferGranularityRequirements(dev_data, cb_node, src_image_state, &pRegions[i], i,
+                                                                                "CmdCopyImageToBuffer");
         }
     } else {
         assert(0);
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount,
-                                                              pRegions);
+        dev_data->dispatch_table.CmdCopyImageToBuffer(commandBuffer, srcImage, srcImageLayout, dstBuffer, regionCount, pRegions);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdUpdateBuffer(VkCommandBuffer commandBuffer, VkBuffer dstBuffer,
@@ -8051,7 +8438,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
+        dev_data->dispatch_table.CmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, dataSize, pData);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8082,7 +8469,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
+        dev_data->dispatch_table.CmdFillBuffer(commandBuffer, dstBuffer, dstOffset, size, data);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdClearAttachments(VkCommandBuffer commandBuffer, uint32_t attachmentCount,
@@ -8097,14 +8484,14 @@
         // Warn if this is issued prior to Draw Cmd and clearing the entire attachment
         if (!hasDrawCmd(pCB) && (pCB->activeRenderPassBeginInfo.renderArea.extent.width == pRects[0].rect.extent.width) &&
             (pCB->activeRenderPassBeginInfo.renderArea.extent.height == pRects[0].rect.extent.height)) {
-            // TODO : commandBuffer should be srcObj
             // There are times where app needs to use ClearAttachments (generally when reusing a buffer inside of a render pass)
             // Can we make this warning more specific? I'd like to avoid triggering this test if we can tell it's a use that must
             // call CmdClearAttachments
             // Otherwise this seems more like a performance warning.
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, 0, 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
-                                 "vkCmdClearAttachments() issued on CB object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
+                                 VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
+                                 0, DRAWSTATE_CLEAR_CMD_BEFORE_DRAW, "DS",
+                                 "vkCmdClearAttachments() issued on command buffer object 0x%" PRIxLEAST64 " prior to any Draw Cmds."
                                  " It is recommended you use RenderPass LOAD_OP_CLEAR on Attachments prior to any Draw.",
                                  (uint64_t)(commandBuffer));
         }
@@ -8113,7 +8500,7 @@
 
     // Validate that attachment is in reference list of active subpass
     if (pCB->activeRenderPass) {
-        const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->pCreateInfo;
+        const VkRenderPassCreateInfo *pRPCI = pCB->activeRenderPass->createInfo.ptr();
         const VkSubpassDescription *pSD = &pRPCI->pSubpasses[pCB->activeSubpass];
 
         for (uint32_t attachment_idx = 0; attachment_idx < attachmentCount; attachment_idx++) {
@@ -8148,7 +8535,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
+        dev_data->dispatch_table.CmdClearAttachments(commandBuffer, attachmentCount, pAttachments, rectCount, pRects);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdClearColorImage(VkCommandBuffer commandBuffer, VkImage image,
@@ -8160,12 +8547,12 @@
     // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto img_node = getImageNode(dev_data, image);
-    if (cb_node && img_node) {
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, img_node, "vkCmdClearColorImage()");
-        AddCommandBufferBindingImage(dev_data, cb_node, img_node);
+    auto image_state = getImageState(dev_data, image);
+    if (cb_node && image_state) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearColorImage()");
+        AddCommandBufferBindingImage(dev_data, cb_node, image_state);
         std::function<bool()> function = [=]() {
-            SetImageMemoryValid(dev_data, img_node, true);
+            SetImageMemoryValid(dev_data, image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -8177,7 +8564,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
+        dev_data->dispatch_table.CmdClearColorImage(commandBuffer, image, imageLayout, pColor, rangeCount, pRanges);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8190,12 +8577,12 @@
     // TODO : Verify memory is in VK_IMAGE_STATE_CLEAR state
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto img_node = getImageNode(dev_data, image);
-    if (cb_node && img_node) {
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, img_node, "vkCmdClearDepthStencilImage()");
-        AddCommandBufferBindingImage(dev_data, cb_node, img_node);
+    auto image_state = getImageState(dev_data, image);
+    if (cb_node && image_state) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, image_state, "vkCmdClearDepthStencilImage()");
+        AddCommandBufferBindingImage(dev_data, cb_node, image_state);
         std::function<bool()> function = [=]() {
-            SetImageMemoryValid(dev_data, img_node, true);
+            SetImageMemoryValid(dev_data, image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -8207,8 +8594,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount,
-                                                                   pRanges);
+        dev_data->dispatch_table.CmdClearDepthStencilImage(commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8219,20 +8605,20 @@
     std::unique_lock<std::mutex> lock(global_lock);
 
     auto cb_node = getCBNode(dev_data, commandBuffer);
-    auto src_img_node = getImageNode(dev_data, srcImage);
-    auto dst_img_node = getImageNode(dev_data, dstImage);
-    if (cb_node && src_img_node && dst_img_node) {
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_img_node, "vkCmdResolveImage()");
-        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_img_node, "vkCmdResolveImage()");
+    auto src_image_state = getImageState(dev_data, srcImage);
+    auto dst_image_state = getImageState(dev_data, dstImage);
+    if (cb_node && src_image_state && dst_image_state) {
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, src_image_state, "vkCmdResolveImage()");
+        skip_call |= ValidateMemoryIsBoundToImage(dev_data, dst_image_state, "vkCmdResolveImage()");
         // Update bindings between images and cmd buffer
-        AddCommandBufferBindingImage(dev_data, cb_node, src_img_node);
-        AddCommandBufferBindingImage(dev_data, cb_node, dst_img_node);
+        AddCommandBufferBindingImage(dev_data, cb_node, src_image_state);
+        AddCommandBufferBindingImage(dev_data, cb_node, dst_image_state);
         std::function<bool()> function = [=]() {
-            return ValidateImageMemoryIsValid(dev_data, src_img_node, "vkCmdResolveImage()");
+            return ValidateImageMemoryIsValid(dev_data, src_image_state, "vkCmdResolveImage()");
         };
         cb_node->validate_functions.push_back(function);
         function = [=]() {
-            SetImageMemoryValid(dev_data, dst_img_node, true);
+            SetImageMemoryValid(dev_data, dst_image_state, true);
             return false;
         };
         cb_node->validate_functions.push_back(function);
@@ -8244,8 +8630,8 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
-                                                         regionCount, pRegions);
+        dev_data->dispatch_table.CmdResolveImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount,
+                                                 pRegions);
 }
 
 bool setEventStageMask(VkQueue queue, VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags stageMask) {
@@ -8270,11 +8656,11 @@
     if (pCB) {
         skip_call |= addCmd(dev_data, pCB, CMD_SETEVENT, "vkCmdSetEvent()");
         skip_call |= insideRenderPass(dev_data, pCB, "vkCmdSetEvent");
-        auto event_node = getEventNode(dev_data, event);
-        if (event_node) {
-            addCommandBufferBinding(&event_node->cb_bindings,
+        auto event_state = getEventNode(dev_data, event);
+        if (event_state) {
+            addCommandBufferBinding(&event_state->cb_bindings,
                                     {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT}, pCB);
-            event_node->cb_bindings.insert(pCB);
+            event_state->cb_bindings.insert(pCB);
         }
         pCB->events.push_back(event);
         if (!pCB->waitedEvents.count(event)) {
@@ -8286,7 +8672,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdSetEvent(commandBuffer, event, stageMask);
+        dev_data->dispatch_table.CmdSetEvent(commandBuffer, event, stageMask);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8298,11 +8684,11 @@
     if (pCB) {
         skip_call |= addCmd(dev_data, pCB, CMD_RESETEVENT, "vkCmdResetEvent()");
         skip_call |= insideRenderPass(dev_data, pCB, "vkCmdResetEvent");
-        auto event_node = getEventNode(dev_data, event);
-        if (event_node) {
-            addCommandBufferBinding(&event_node->cb_bindings,
+        auto event_state = getEventNode(dev_data, event);
+        if (event_state) {
+            addCommandBufferBinding(&event_state->cb_bindings,
                                     {reinterpret_cast<uint64_t &>(event), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT}, pCB);
-            event_node->cb_bindings.insert(pCB);
+            event_state->cb_bindings.insert(pCB);
         }
         pCB->events.push_back(event);
         if (!pCB->waitedEvents.count(event)) {
@@ -8314,7 +8700,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdResetEvent(commandBuffer, event, stageMask);
+        dev_data->dispatch_table.CmdResetEvent(commandBuffer, event, stageMask);
 }
 
 static bool TransitionImageLayouts(VkCommandBuffer cmdBuffer, uint32_t memBarrierCount,
@@ -8427,12 +8813,12 @@
     switch (layout) {
     case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: {
         skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                                      VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, type);
+                                      VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, type);
         break;
     }
     case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: {
         skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
-                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, type);
+                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, type);
         break;
     }
     case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: {
@@ -8445,7 +8831,8 @@
     }
     case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: {
         skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, 0,
-                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_SHADER_READ_BIT, type);
+                                      VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
+                                      VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, type);
         break;
     }
     case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: {
@@ -8457,6 +8844,10 @@
         skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, VK_ACCESS_TRANSFER_READ_BIT, 0, type);
         break;
     }
+    case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
+        skip_call |= ValidateMaskBits(my_data, cmdBuffer, accessMask, layout, VK_ACCESS_MEMORY_READ_BIT, 0, type);
+        break;
+    }
     case VK_IMAGE_LAYOUT_UNDEFINED: {
         if (accessMask != 0) {
             // TODO: Verify against Valid Use section spec
@@ -8490,7 +8881,7 @@
     }
     for (uint32_t i = 0; i < imageMemBarrierCount; ++i) {
         auto mem_barrier = &pImageMemBarriers[i];
-        auto image_data = getImageNode(dev_data, mem_barrier->image);
+        auto image_data = getImageState(dev_data, mem_barrier->image);
         if (image_data) {
             uint32_t src_q_f_index = mem_barrier->srcQueueFamilyIndex;
             uint32_t dst_q_f_index = mem_barrier->dstQueueFamilyIndex;
@@ -8534,17 +8925,19 @@
         }
 
         if (mem_barrier) {
-            skip_call |=
-                ValidateMaskBitsFromLayouts(dev_data, cmdBuffer, mem_barrier->srcAccessMask, mem_barrier->oldLayout, "Source");
-            skip_call |=
-                ValidateMaskBitsFromLayouts(dev_data, cmdBuffer, mem_barrier->dstAccessMask, mem_barrier->newLayout, "Dest");
+            if (mem_barrier->oldLayout != mem_barrier->newLayout) {
+                skip_call |=
+                    ValidateMaskBitsFromLayouts(dev_data, cmdBuffer, mem_barrier->srcAccessMask, mem_barrier->oldLayout, "Source");
+                skip_call |=
+                    ValidateMaskBitsFromLayouts(dev_data, cmdBuffer, mem_barrier->dstAccessMask, mem_barrier->newLayout, "Dest");
+            }
             if (mem_barrier->newLayout == VK_IMAGE_LAYOUT_UNDEFINED || mem_barrier->newLayout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_BARRIER, "DS", "%s: Image Layout cannot be transitioned to UNDEFINED or "
                                                          "PREINITIALIZED.",
                         funcName);
             }
-            auto image_data = getImageNode(dev_data, mem_barrier->image);
+            auto image_data = getImageState(dev_data, mem_barrier->image);
             VkFormat format = VK_FORMAT_UNDEFINED;
             uint32_t arrayLayers = 0, mipLevels = 0;
             bool imageFound = false;
@@ -8650,7 +9043,7 @@
 
         auto buffer_node = getBufferNode(dev_data, mem_barrier->buffer);
         if (buffer_node) {
-            auto buffer_size = buffer_node->memSize;
+            auto buffer_size = buffer_node->binding.size;
             if (mem_barrier->offset >= buffer_size) {
                 skip_call |= log_msg(
                     dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -8722,12 +9115,12 @@
     if (pCB) {
         auto firstEventIndex = pCB->events.size();
         for (uint32_t i = 0; i < eventCount; ++i) {
-            auto event_node = getEventNode(dev_data, pEvents[i]);
-            if (event_node) {
-                addCommandBufferBinding(&event_node->cb_bindings,
+            auto event_state = getEventNode(dev_data, pEvents[i]);
+            if (event_state) {
+                addCommandBufferBinding(&event_state->cb_bindings,
                                         {reinterpret_cast<const uint64_t &>(pEvents[i]), VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT},
                                         pCB);
-                event_node->cb_bindings.insert(pCB);
+                event_state->cb_bindings.insert(pCB);
             }
             pCB->waitedEvents.insert(pEvents[i]);
             pCB->events.push_back(pEvents[i]);
@@ -8747,9 +9140,9 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask,
-                                                       memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                                                       pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+        dev_data->dispatch_table.CmdWaitEvents(commandBuffer, eventCount, pEvents, sourceStageMask, dstStageMask,
+                                               memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
+                                               imageMemoryBarrierCount, pImageMemoryBarriers);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8770,9 +9163,9 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags,
-                                                            memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount,
-                                                            pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
+        dev_data->dispatch_table.CmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, dependencyFlags, memoryBarrierCount,
+                                                    pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers,
+                                                    imageMemoryBarrierCount, pImageMemoryBarriers);
 }
 
 bool setQueryState(VkQueue queue, VkCommandBuffer commandBuffer, QueryObject object, bool value) {
@@ -8806,7 +9199,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdBeginQuery(commandBuffer, queryPool, slot, flags);
+        dev_data->dispatch_table.CmdBeginQuery(commandBuffer, queryPool, slot, flags);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdEndQuery(VkCommandBuffer commandBuffer, VkQueryPool queryPool, uint32_t slot) {
@@ -8836,7 +9229,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdEndQuery(commandBuffer, queryPool, slot);
+        dev_data->dispatch_table.CmdEndQuery(commandBuffer, queryPool, slot);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -8863,7 +9256,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
+        dev_data->dispatch_table.CmdResetQueryPool(commandBuffer, queryPool, firstQuery, queryCount);
 }
 
 bool validateQuery(VkQueue queue, GLOBAL_CB_NODE *pCB, VkQueryPool queryPool, uint32_t queryCount, uint32_t firstQuery) {
@@ -8937,8 +9330,8 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer,
-                                                                 dstOffset, stride, flags);
+        dev_data->dispatch_table.CmdCopyQueryPoolResults(commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset,
+                                                         stride, flags);
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout,
@@ -9029,7 +9422,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
+        dev_data->dispatch_table.CmdPushConstants(commandBuffer, layout, stageFlags, offset, size, pValues);
 }
 
 VKAPI_ATTR void VKAPI_CALL
@@ -9050,7 +9443,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
+        dev_data->dispatch_table.CmdWriteTimestamp(commandBuffer, pipelineStage, queryPool, slot);
 }
 
 static bool MatchUsage(layer_data *dev_data, uint32_t count, const VkAttachmentReference *attachments,
@@ -9062,9 +9455,9 @@
             // Attachment counts are verified elsewhere, but prevent an invalid access
             if (attachments[attach].attachment < fbci->attachmentCount) {
                 const VkImageView *image_view = &fbci->pAttachments[attachments[attach].attachment];
-                VkImageViewCreateInfo *ivci = getImageViewData(dev_data, *image_view);
-                if (ivci != nullptr) {
-                    const VkImageCreateInfo *ici = &getImageNode(dev_data, ivci->image)->createInfo;
+                auto view_state = getImageViewState(dev_data, *image_view);
+                if (view_state) {
+                    const VkImageCreateInfo *ici = &getImageState(dev_data, view_state->create_info.image)->createInfo;
                     if (ici != nullptr) {
                         if ((ici->usage & usage_flag) == 0) {
                             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -9093,9 +9486,9 @@
 static bool ValidateFramebufferCreateInfo(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo) {
     bool skip_call = false;
 
-    auto rp_node = getRenderPass(dev_data, pCreateInfo->renderPass);
-    if (rp_node) {
-        const VkRenderPassCreateInfo *rpci = rp_node->pCreateInfo;
+    auto rp_state = getRenderPassState(dev_data, pCreateInfo->renderPass);
+    if (rp_state) {
+        const VkRenderPassCreateInfo *rpci = rp_state->createInfo.ptr();
         if (rpci->attachmentCount != pCreateInfo->attachmentCount) {
             skip_call |= log_msg(
                 dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
@@ -9107,18 +9500,19 @@
             // attachmentCounts match, so make sure corresponding attachment details line up
             const VkImageView *image_views = pCreateInfo->pAttachments;
             for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
-                VkImageViewCreateInfo *ivci = getImageViewData(dev_data, image_views[i]);
-                if (ivci->format != rpci->pAttachments[i].format) {
+                auto view_state = getImageViewState(dev_data, image_views[i]);
+                auto &ivci = view_state->create_info;
+                if (ivci.format != rpci->pAttachments[i].format) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
                         reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE,
                         "DS", "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has format of %s that does not match "
                               "the format of "
                               "%s used by the corresponding attachment for renderPass (0x%" PRIxLEAST64 ").",
-                        i, string_VkFormat(ivci->format), string_VkFormat(rpci->pAttachments[i].format),
+                        i, string_VkFormat(ivci.format), string_VkFormat(rpci->pAttachments[i].format),
                         reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
                 }
-                const VkImageCreateInfo *ici = &getImageNode(dev_data, ivci->image)->createInfo;
+                const VkImageCreateInfo *ici = &getImageState(dev_data, ivci.image)->createInfo;
                 if (ici->samples != rpci->pAttachments[i].samples) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
@@ -9129,17 +9523,17 @@
                         reinterpret_cast<const uint64_t &>(pCreateInfo->renderPass));
                 }
                 // Verify that view only has a single mip level
-                if (ivci->subresourceRange.levelCount != 1) {
+                if (ivci.subresourceRange.levelCount != 1) {
                     skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0,
                                          __LINE__, DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
                                          "vkCreateFramebuffer(): VkFramebufferCreateInfo attachment #%u has mip levelCount of %u "
                                          "but only a single mip level (levelCount ==  1) is allowed when creating a Framebuffer.",
-                                         i, ivci->subresourceRange.levelCount);
+                                         i, ivci.subresourceRange.levelCount);
                 }
-                const uint32_t mip_level = ivci->subresourceRange.baseMipLevel;
+                const uint32_t mip_level = ivci.subresourceRange.baseMipLevel;
                 uint32_t mip_width = max(1u, ici->extent.width >> mip_level);
                 uint32_t mip_height = max(1u, ici->extent.height >> mip_level);
-                if ((ivci->subresourceRange.layerCount < pCreateInfo->layers) || (mip_width < pCreateInfo->width) ||
+                if ((ivci.subresourceRange.layerCount < pCreateInfo->layers) || (mip_width < pCreateInfo->width) ||
                     (mip_height < pCreateInfo->height)) {
                     skip_call |=
                         log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
@@ -9152,13 +9546,13 @@
                                 "width: %u, %u\n"
                                 "height: %u, %u\n"
                                 "layerCount: %u, %u\n",
-                                i, ivci->subresourceRange.baseMipLevel, i, mip_width, pCreateInfo->width, mip_height,
-                                pCreateInfo->height, ivci->subresourceRange.layerCount, pCreateInfo->layers);
+                                i, ivci.subresourceRange.baseMipLevel, i, mip_width, pCreateInfo->width, mip_height,
+                                pCreateInfo->height, ivci.subresourceRange.layerCount, pCreateInfo->layers);
                 }
-                if (((ivci->components.r != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.r != VK_COMPONENT_SWIZZLE_R)) ||
-                    ((ivci->components.g != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.g != VK_COMPONENT_SWIZZLE_G)) ||
-                    ((ivci->components.b != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.b != VK_COMPONENT_SWIZZLE_B)) ||
-                    ((ivci->components.a != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci->components.a != VK_COMPONENT_SWIZZLE_A))) {
+                if (((ivci.components.r != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.r != VK_COMPONENT_SWIZZLE_R)) ||
+                    ((ivci.components.g != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.g != VK_COMPONENT_SWIZZLE_G)) ||
+                    ((ivci.components.b != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.b != VK_COMPONENT_SWIZZLE_B)) ||
+                    ((ivci.components.a != VK_COMPONENT_SWIZZLE_IDENTITY) && (ivci.components.a != VK_COMPONENT_SWIZZLE_A))) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VkDebugReportObjectTypeEXT(0), 0, __LINE__,
                         DRAWSTATE_INVALID_FRAMEBUFFER_CREATE_INFO, "DS",
@@ -9168,8 +9562,8 @@
                         "g swizzle = %s\n"
                         "b swizzle = %s\n"
                         "a swizzle = %s\n",
-                        i, string_VkComponentSwizzle(ivci->components.r), string_VkComponentSwizzle(ivci->components.g),
-                        string_VkComponentSwizzle(ivci->components.b), string_VkComponentSwizzle(ivci->components.a));
+                        i, string_VkComponentSwizzle(ivci.components.r), string_VkComponentSwizzle(ivci.components.g),
+                        string_VkComponentSwizzle(ivci.components.b), string_VkComponentSwizzle(ivci.components.a));
                 }
             }
         }
@@ -9225,21 +9619,22 @@
 // CreateFramebuffer state has been validated and call down chain completed so record new framebuffer object
 static void PostCallRecordCreateFramebuffer(layer_data *dev_data, const VkFramebufferCreateInfo *pCreateInfo, VkFramebuffer fb) {
     // Shadow create info and store in map
-    std::unique_ptr<FRAMEBUFFER_NODE> fb_node(
-        new FRAMEBUFFER_NODE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->pCreateInfo));
+    std::unique_ptr<FRAMEBUFFER_STATE> fb_state(
+        new FRAMEBUFFER_STATE(fb, pCreateInfo, dev_data->renderPassMap[pCreateInfo->renderPass]->createInfo.ptr()));
 
     for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
         VkImageView view = pCreateInfo->pAttachments[i];
-        auto view_data = getImageViewData(dev_data, view);
-        if (!view_data) {
+        auto view_state = getImageViewState(dev_data, view);
+        if (!view_state) {
             continue;
         }
         MT_FB_ATTACHMENT_INFO fb_info;
-        fb_info.mem = getImageNode(dev_data, view_data->image)->mem;
-        fb_info.image = view_data->image;
-        fb_node->attachments.push_back(fb_info);
+        fb_info.mem = getImageState(dev_data, view_state->create_info.image)->binding.mem;
+        fb_info.view_state = view_state;
+        fb_info.image = view_state->create_info.image;
+        fb_state->attachments.push_back(fb_info);
     }
-    dev_data->frameBufferMap[fb] = std::move(fb_node);
+    dev_data->frameBufferMap[fb] = std::move(fb_state);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo *pCreateInfo,
@@ -9253,7 +9648,7 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result = dev_data->device_dispatch_table->CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
+    VkResult result = dev_data->dispatch_table.CreateFramebuffer(device, pCreateInfo, pAllocator, pFramebuffer);
 
     if (VK_SUCCESS == result) {
         lock.lock();
@@ -9282,7 +9677,7 @@
     return false;
 }
 
-static bool CheckDependencyExists(const layer_data *my_data, const int subpass, const std::vector<uint32_t> &dependent_subpasses,
+static bool CheckDependencyExists(const layer_data *dev_data, const int subpass, const std::vector<uint32_t> &dependent_subpasses,
                                   const std::vector<DAGNode> &subpass_to_node, bool &skip_call) {
     bool result = true;
     // Loop through all subpasses that share the same attachment and make sure a dependency exists
@@ -9298,7 +9693,7 @@
             std::unordered_set<uint32_t> processed_nodes;
             if (!(FindDependency(subpass, dependent_subpasses[k], subpass_to_node, processed_nodes) ||
                 FindDependency(dependent_subpasses[k], subpass, subpass_to_node, processed_nodes))) {
-                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0,
                                      __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
                                      "A dependency between subpasses %d and %d must exist but one is not specified.", subpass,
                                      dependent_subpasses[k]);
@@ -9309,7 +9704,7 @@
     return result;
 }
 
-static bool CheckPreserved(const layer_data *my_data, const VkRenderPassCreateInfo *pCreateInfo, const int index,
+static bool CheckPreserved(const layer_data *dev_data, const VkRenderPassCreateInfo *pCreateInfo, const int index,
                            const uint32_t attachment, const std::vector<DAGNode> &subpass_to_node, int depth, bool &skip_call) {
     const DAGNode &node = subpass_to_node[index];
     // If this node writes to the attachment return true as next nodes need to preserve the attachment.
@@ -9325,7 +9720,7 @@
     bool result = false;
     // Loop through previous nodes and see if any of them write to the attachment.
     for (auto elem : node.prev) {
-        result |= CheckPreserved(my_data, pCreateInfo, elem, attachment, subpass_to_node, depth + 1, skip_call);
+        result |= CheckPreserved(dev_data, pCreateInfo, elem, attachment, subpass_to_node, depth + 1, skip_call);
     }
     // If the attachment was written to by a previous node than this node needs to preserve it.
     if (result && depth > 0) {
@@ -9339,7 +9734,7 @@
         }
         if (!has_preserved) {
             skip_call |=
-                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                         DRAWSTATE_INVALID_RENDERPASS, "DS",
                         "Attachment %d is used by a later subpass and must be preserved in subpass %d.", attachment, index);
         }
@@ -9357,11 +9752,11 @@
             isRangeOverlapping(range1.baseArrayLayer, range1.layerCount, range2.baseArrayLayer, range2.layerCount));
 }
 
-static bool ValidateDependencies(const layer_data *my_data, FRAMEBUFFER_NODE const * framebuffer,
-                                 RENDER_PASS_NODE const * renderPass) {
+static bool ValidateDependencies(const layer_data *dev_data, FRAMEBUFFER_STATE const *framebuffer,
+                                 RENDER_PASS_STATE const *renderPass) {
     bool skip_call = false;
-    const safe_VkFramebufferCreateInfo *pFramebufferInfo = &framebuffer->createInfo;
-    const VkRenderPassCreateInfo *pCreateInfo = renderPass->pCreateInfo;
+    auto const pFramebufferInfo = framebuffer->createInfo.ptr();
+    auto const pCreateInfo = renderPass->createInfo.ptr();
     auto const & subpass_to_node = renderPass->subpassToNode;
     std::vector<std::vector<uint32_t>> output_attachment_to_subpass(pCreateInfo->attachmentCount);
     std::vector<std::vector<uint32_t>> input_attachment_to_subpass(pCreateInfo->attachmentCount);
@@ -9376,24 +9771,26 @@
                 overlapping_attachments[j].push_back(i);
                 continue;
             }
-            auto view_data_i = getImageViewData(my_data, viewi);
-            auto view_data_j = getImageViewData(my_data, viewj);
-            if (!view_data_i || !view_data_j) {
+            auto view_state_i = getImageViewState(dev_data, viewi);
+            auto view_state_j = getImageViewState(dev_data, viewj);
+            if (!view_state_i || !view_state_j) {
                 continue;
             }
-            if (view_data_i->image == view_data_j->image &&
-                isRegionOverlapping(view_data_i->subresourceRange, view_data_j->subresourceRange)) {
+            auto view_ci_i = view_state_i->create_info;
+            auto view_ci_j = view_state_j->create_info;
+            if (view_ci_i.image == view_ci_j.image && isRegionOverlapping(view_ci_i.subresourceRange, view_ci_j.subresourceRange)) {
                 overlapping_attachments[i].push_back(j);
                 overlapping_attachments[j].push_back(i);
                 continue;
             }
-            auto image_data_i = getImageNode(my_data, view_data_i->image);
-            auto image_data_j = getImageNode(my_data, view_data_j->image);
+            auto image_data_i = getImageState(dev_data, view_ci_i.image);
+            auto image_data_j = getImageState(dev_data, view_ci_j.image);
             if (!image_data_i || !image_data_j) {
                 continue;
             }
-            if (image_data_i->mem == image_data_j->mem && isRangeOverlapping(image_data_i->memOffset, image_data_i->memSize,
-                                                                             image_data_j->memOffset, image_data_j->memSize)) {
+            if (image_data_i->binding.mem == image_data_j->binding.mem &&
+                isRangeOverlapping(image_data_i->binding.offset, image_data_i->binding.size, image_data_j->binding.offset,
+                                   image_data_j->binding.size)) {
                 overlapping_attachments[i].push_back(j);
                 overlapping_attachments[j].push_back(i);
             }
@@ -9404,14 +9801,14 @@
         for (auto other_attachment : overlapping_attachments[i]) {
             if (!(pCreateInfo->pAttachments[attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) {
                 skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                             DRAWSTATE_INVALID_RENDERPASS, "DS", "Attachment %d aliases attachment %d but doesn't "
                                                                 "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT.",
                             attachment, other_attachment);
             }
             if (!(pCreateInfo->pAttachments[other_attachment].flags & VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT)) {
                 skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                             DRAWSTATE_INVALID_RENDERPASS, "DS", "Attachment %d aliases attachment %d but doesn't "
                                                                 "set VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT.",
                             other_attachment, attachment);
@@ -9451,10 +9848,9 @@
 
             if (attachmentIndices.count(attachment)) {
                 skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0,
-                            0, __LINE__, DRAWSTATE_INVALID_RENDERPASS, "DS",
-                            "Cannot use same attachment (%u) as both color and depth output in same subpass (%u).",
-                            attachment, i);
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_INVALID_RENDERPASS, "DS",
+                            "Cannot use same attachment (%u) as both color and depth output in same subpass (%u).", attachment, i);
             }
         }
     }
@@ -9466,20 +9862,20 @@
             uint32_t attachment = subpass.pInputAttachments[j].attachment;
             if (attachment == VK_ATTACHMENT_UNUSED)
                 continue;
-            CheckDependencyExists(my_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+            CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
         }
         // If the attachment is an output then all subpasses that use the attachment must have a dependency relationship
         for (uint32_t j = 0; j < subpass.colorAttachmentCount; ++j) {
             uint32_t attachment = subpass.pColorAttachments[j].attachment;
             if (attachment == VK_ATTACHMENT_UNUSED)
                 continue;
-            CheckDependencyExists(my_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
-            CheckDependencyExists(my_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+            CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+            CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
         }
         if (subpass.pDepthStencilAttachment && subpass.pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) {
             const uint32_t &attachment = subpass.pDepthStencilAttachment->attachment;
-            CheckDependencyExists(my_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
-            CheckDependencyExists(my_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+            CheckDependencyExists(dev_data, i, output_attachment_to_subpass[attachment], subpass_to_node, skip_call);
+            CheckDependencyExists(dev_data, i, input_attachment_to_subpass[attachment], subpass_to_node, skip_call);
         }
     }
     // Loop through implicit dependencies, if this pass reads make sure the attachment is preserved for all passes after it was
@@ -9487,7 +9883,7 @@
     for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
         const VkSubpassDescription &subpass = pCreateInfo->pSubpasses[i];
         for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
-            CheckPreserved(my_data, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip_call);
+            CheckPreserved(dev_data, pCreateInfo, i, subpass.pInputAttachments[j].attachment, subpass_to_node, 0, skip_call);
         }
     }
     return skip_call;
@@ -9512,7 +9908,7 @@
     return skip_call;
 }
 
-static bool ValidateLayouts(const layer_data *my_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) {
+static bool ValidateLayouts(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo) {
     bool skip = false;
 
     // Track when we're observing the first use of an attachment
@@ -9533,22 +9929,20 @@
                 /* May not be optimal; TODO: reconsider this warning based on
                  * other constraints?
                  */
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "Layout for color attachment is GENERAL but should be COLOR_ATTACHMENT_OPTIMAL.");
                 break;
 
             default:
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "Layout for color attachment is %s but can only be COLOR_ATTACHMENT_OPTIMAL or GENERAL.",
                                 string_VkImageLayout(subpass.pColorAttachments[j].layout));
             }
 
             if (attach_first_use[attach_index]) {
-                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pColorAttachments[j].layout,
+                skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pColorAttachments[j].layout,
                                                               attach_index, pCreateInfo->pAttachments[attach_index]);
             }
             attach_first_use[attach_index] = false;
@@ -9565,17 +9959,15 @@
                  * other constraints? GENERAL can be better than doing a bunch
                  * of transitions.
                  */
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "GENERAL layout for depth attachment may not give optimal performance.");
                 break;
 
             default:
                 /* No other layouts are acceptable */
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "Layout for depth attachment is %s but can only be DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "
                                 "DEPTH_STENCIL_READ_ONLY_OPTIMAL or GENERAL.",
                                 string_VkImageLayout(subpass.pDepthStencilAttachment->layout));
@@ -9583,7 +9975,7 @@
 
             auto attach_index = subpass.pDepthStencilAttachment->attachment;
             if (attach_first_use[attach_index]) {
-                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pDepthStencilAttachment->layout,
+                skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pDepthStencilAttachment->layout,
                                                               attach_index, pCreateInfo->pAttachments[attach_index]);
             }
             attach_first_use[attach_index] = false;
@@ -9603,22 +9995,21 @@
                 /* May not be optimal. TODO: reconsider this warning based on
                  * other constraints.
                  */
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                                DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "Layout for input attachment is GENERAL but should be READ_ONLY_OPTIMAL.");
                 break;
 
             default:
                 /* No other layouts are acceptable */
-                skip |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                skip |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                 DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
                                 "Layout for input attachment is %s but can only be READ_ONLY_OPTIMAL or GENERAL.",
                                 string_VkImageLayout(subpass.pInputAttachments[j].layout));
             }
 
             if (attach_first_use[attach_index]) {
-                skip |= ValidateLayoutVsAttachmentDescription(my_data->report_data, subpass.pInputAttachments[j].layout,
+                skip |= ValidateLayoutVsAttachmentDescription(dev_data->report_data, subpass.pInputAttachments[j].layout,
                                                               attach_index, pCreateInfo->pAttachments[attach_index]);
             }
             attach_first_use[attach_index] = false;
@@ -9627,7 +10018,7 @@
     return skip;
 }
 
-static bool CreatePassDAG(const layer_data *my_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
+static bool CreatePassDAG(const layer_data *dev_data, VkDevice device, const VkRenderPassCreateInfo *pCreateInfo,
                           std::vector<DAGNode> &subpass_to_node, std::vector<bool> &has_self_dependency) {
     bool skip_call = false;
     for (uint32_t i = 0; i < pCreateInfo->subpassCount; ++i) {
@@ -9636,23 +10027,27 @@
     }
     for (uint32_t i = 0; i < pCreateInfo->dependencyCount; ++i) {
         const VkSubpassDependency &dependency = pCreateInfo->pDependencies[i];
-        if (dependency.srcSubpass > dependency.dstSubpass && dependency.srcSubpass != VK_SUBPASS_EXTERNAL &&
-            dependency.dstSubpass != VK_SUBPASS_EXTERNAL) {
-            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+        if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL || dependency.dstSubpass == VK_SUBPASS_EXTERNAL) {
+            if (dependency.srcSubpass == dependency.dstSubpass) {
+                skip_call |=
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+                            DRAWSTATE_INVALID_RENDERPASS, "DS", "The src and dest subpasses cannot both be external.");
+            }
+
+            // We don't want to add edges to the DAG for dependencies to/from
+            // VK_SUBPASS_EXTERNAL. We don't use them for anything, and their
+            // presence complicates other code.
+            continue;
+        } else if (dependency.srcSubpass > dependency.dstSubpass) {
+            skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                  DRAWSTATE_INVALID_RENDERPASS, "DS",
                                  "Depedency graph must be specified such that an earlier pass cannot depend on a later pass.");
-        } else if (dependency.srcSubpass == VK_SUBPASS_EXTERNAL && dependency.dstSubpass == VK_SUBPASS_EXTERNAL) {
-            skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
-                                 DRAWSTATE_INVALID_RENDERPASS, "DS", "The src and dest subpasses cannot both be external.");
         } else if (dependency.srcSubpass == dependency.dstSubpass) {
             has_self_dependency[dependency.srcSubpass] = true;
         }
-        if (dependency.dstSubpass != VK_SUBPASS_EXTERNAL) {
-            subpass_to_node[dependency.dstSubpass].prev.push_back(dependency.srcSubpass);
-        }
-        if (dependency.srcSubpass != VK_SUBPASS_EXTERNAL) {
-            subpass_to_node[dependency.srcSubpass].next.push_back(dependency.dstSubpass);
-        }
+
+        subpass_to_node[dependency.dstSubpass].prev.push_back(dependency.srcSubpass);
+        subpass_to_node[dependency.srcSubpass].next.push_back(dependency.dstSubpass);
     }
     return skip_call;
 }
@@ -9661,7 +10056,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo *pCreateInfo,
                                                   const VkAllocationCallbacks *pAllocator,
                                                   VkShaderModule *pShaderModule) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     bool skip_call = false;
 
     /* Use SPIRV-Tools validator to try and catch any issues with the module itself */
@@ -9671,11 +10066,10 @@
 
     auto result = spvValidate(ctx, &binary, &diag);
     if (result != SPV_SUCCESS) {
-        skip_call |= log_msg(my_data->report_data,
-                             result == SPV_WARNING ? VK_DEBUG_REPORT_WARNING_BIT_EXT : VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                             VkDebugReportObjectTypeEXT(0), 0,
-                             __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", "SPIR-V module not valid: %s",
-                             diag && diag->error ? diag->error : "(no error text)");
+        skip_call |=
+            log_msg(dev_data->report_data, result == SPV_WARNING ? VK_DEBUG_REPORT_WARNING_BIT_EXT : VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                    VkDebugReportObjectTypeEXT(0), 0, __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC",
+                    "SPIR-V module not valid: %s", diag && diag->error ? diag->error : "(no error text)");
     }
 
     spvDiagnosticDestroy(diag);
@@ -9684,11 +10078,11 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult res = my_data->device_dispatch_table->CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
+    VkResult res = dev_data->dispatch_table.CreateShaderModule(device, pCreateInfo, pAllocator, pShaderModule);
 
     if (res == VK_SUCCESS) {
         std::lock_guard<std::mutex> lock(global_lock);
-        my_data->shaderModuleMap[*pShaderModule] = unique_ptr<shader_module>(new shader_module(pCreateInfo));
+        dev_data->shaderModuleMap[*pShaderModule] = unique_ptr<shader_module>(new shader_module(pCreateInfo));
     }
     return res;
 }
@@ -9809,7 +10203,7 @@
         return VK_ERROR_VALIDATION_FAILED_EXT;
     }
 
-    VkResult result = dev_data->device_dispatch_table->CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
+    VkResult result = dev_data->dispatch_table.CreateRenderPass(device, pCreateInfo, pAllocator, pRenderPass);
 
     if (VK_SUCCESS == result) {
         lock.lock();
@@ -9818,70 +10212,11 @@
         std::vector<DAGNode> subpass_to_node(pCreateInfo->subpassCount);
         skip_call |= CreatePassDAG(dev_data, device, pCreateInfo, subpass_to_node, has_self_dependency);
 
-        // Shadow create info and store in map
-        VkRenderPassCreateInfo *localRPCI = new VkRenderPassCreateInfo(*pCreateInfo);
-        if (pCreateInfo->pAttachments) {
-            localRPCI->pAttachments = new VkAttachmentDescription[localRPCI->attachmentCount];
-            memcpy((void *)localRPCI->pAttachments, pCreateInfo->pAttachments,
-                   localRPCI->attachmentCount * sizeof(VkAttachmentDescription));
-        }
-        if (pCreateInfo->pSubpasses) {
-            localRPCI->pSubpasses = new VkSubpassDescription[localRPCI->subpassCount];
-            memcpy((void *)localRPCI->pSubpasses, pCreateInfo->pSubpasses, localRPCI->subpassCount * sizeof(VkSubpassDescription));
-
-            for (uint32_t i = 0; i < localRPCI->subpassCount; i++) {
-                VkSubpassDescription *subpass = (VkSubpassDescription *)&localRPCI->pSubpasses[i];
-                const uint32_t attachmentCount = subpass->inputAttachmentCount +
-                                                 subpass->colorAttachmentCount * (1 + (subpass->pResolveAttachments ? 1 : 0)) +
-                                                 ((subpass->pDepthStencilAttachment) ? 1 : 0) + subpass->preserveAttachmentCount;
-                VkAttachmentReference *attachments = new VkAttachmentReference[attachmentCount];
-
-                memcpy(attachments, subpass->pInputAttachments, sizeof(attachments[0]) * subpass->inputAttachmentCount);
-                subpass->pInputAttachments = attachments;
-                attachments += subpass->inputAttachmentCount;
-
-                memcpy(attachments, subpass->pColorAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
-                subpass->pColorAttachments = attachments;
-                attachments += subpass->colorAttachmentCount;
-
-                if (subpass->pResolveAttachments) {
-                    memcpy(attachments, subpass->pResolveAttachments, sizeof(attachments[0]) * subpass->colorAttachmentCount);
-                    subpass->pResolveAttachments = attachments;
-                    attachments += subpass->colorAttachmentCount;
-                }
-
-                if (subpass->pDepthStencilAttachment) {
-                    memcpy(attachments, subpass->pDepthStencilAttachment, sizeof(attachments[0]) * 1);
-                    subpass->pDepthStencilAttachment = attachments;
-                    attachments += 1;
-                }
-
-                memcpy(attachments, subpass->pPreserveAttachments, sizeof(attachments[0]) * subpass->preserveAttachmentCount);
-                subpass->pPreserveAttachments = &attachments->attachment;
-            }
-        }
-        if (pCreateInfo->pDependencies) {
-            localRPCI->pDependencies = new VkSubpassDependency[localRPCI->dependencyCount];
-            memcpy((void *)localRPCI->pDependencies, pCreateInfo->pDependencies,
-                   localRPCI->dependencyCount * sizeof(VkSubpassDependency));
-        }
-
-        auto render_pass = new RENDER_PASS_NODE(localRPCI);
+        auto render_pass = unique_ptr<RENDER_PASS_STATE>(new RENDER_PASS_STATE(pCreateInfo));
         render_pass->renderPass = *pRenderPass;
         render_pass->hasSelfDependency = has_self_dependency;
         render_pass->subpassToNode = subpass_to_node;
-#if MTMERGESOURCE
-        // MTMTODO : Merge with code from above to eliminate duplication
-        for (uint32_t i = 0; i < pCreateInfo->attachmentCount; ++i) {
-            VkAttachmentDescription desc = pCreateInfo->pAttachments[i];
-            MT_PASS_ATTACHMENT_INFO pass_info;
-            pass_info.load_op = desc.loadOp;
-            pass_info.store_op = desc.storeOp;
-            pass_info.stencil_load_op = desc.stencilLoadOp;
-            pass_info.stencil_store_op = desc.stencilStoreOp;
-            pass_info.attachment = i;
-            render_pass->attachments.push_back(pass_info);
-        }
+
         // TODO: Maybe fill list and then copy instead of locking
         std::unordered_map<uint32_t, bool> &attachment_first_read = render_pass->attachment_first_read;
         std::unordered_map<uint32_t, VkImageLayout> &attachment_first_layout = render_pass->attachment_first_layout;
@@ -9909,44 +10244,16 @@
                 }
             }
         }
-#endif
-        dev_data->renderPassMap[*pRenderPass] = render_pass;
+
+        dev_data->renderPassMap[*pRenderPass] = std::move(render_pass);
     }
     return result;
 }
 
-// Free the renderpass shadow
-static void deleteRenderPasses(layer_data *my_data) {
-    for (auto renderPass : my_data->renderPassMap) {
-        const VkRenderPassCreateInfo *pRenderPassInfo = renderPass.second->pCreateInfo;
-        delete[] pRenderPassInfo->pAttachments;
-        if (pRenderPassInfo->pSubpasses) {
-            for (uint32_t i = 0; i < pRenderPassInfo->subpassCount; ++i) {
-                // Attachements are all allocated in a block, so just need to
-                //  find the first non-null one to delete
-                if (pRenderPassInfo->pSubpasses[i].pInputAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pInputAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pColorAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pColorAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pResolveAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pResolveAttachments;
-                } else if (pRenderPassInfo->pSubpasses[i].pPreserveAttachments) {
-                    delete[] pRenderPassInfo->pSubpasses[i].pPreserveAttachments;
-                }
-            }
-            delete[] pRenderPassInfo->pSubpasses;
-        }
-        delete[] pRenderPassInfo->pDependencies;
-        delete pRenderPassInfo;
-        delete renderPass.second;
-    }
-    my_data->renderPassMap.clear();
-}
-
 static bool VerifyFramebufferAndRenderPassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin) {
     bool skip_call = false;
-    const VkRenderPassCreateInfo *pRenderPassInfo = dev_data->renderPassMap[pRenderPassBegin->renderPass]->pCreateInfo;
-    const safe_VkFramebufferCreateInfo framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer]->createInfo;
+    auto const pRenderPassInfo = getRenderPassState(dev_data, pRenderPassBegin->renderPass)->createInfo.ptr();
+    auto const & framebufferInfo = dev_data->frameBufferMap[pRenderPassBegin->framebuffer]->createInfo;
     if (pRenderPassInfo->attachmentCount != framebufferInfo.attachmentCount) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_RENDERPASS, "DS", "You cannot start a render pass using a framebuffer "
@@ -9954,10 +10261,10 @@
     }
     for (uint32_t i = 0; i < pRenderPassInfo->attachmentCount; ++i) {
         const VkImageView &image_view = framebufferInfo.pAttachments[i];
-        auto image_data = getImageViewData(dev_data, image_view);
-        assert(image_data);
-        const VkImage &image = image_data->image;
-        const VkImageSubresourceRange &subRange = image_data->subresourceRange;
+        auto view_state = getImageViewState(dev_data, image_view);
+        assert(view_state);
+        const VkImage &image = view_state->create_info.image;
+        const VkImageSubresourceRange &subRange = view_state->create_info.subresourceRange;
         IMAGE_CMD_BUF_LAYOUT_NODE newNode = {pRenderPassInfo->pAttachments[i].initialLayout,
                                              pRenderPassInfo->pAttachments[i].initialLayout};
         // TODO: Do not iterate over every possibility - consolidate where possible
@@ -9989,10 +10296,8 @@
     return skip_call;
 }
 
-static void TransitionAttachmentRefLayout(layer_data *dev_data, GLOBAL_CB_NODE *pCB,
-                                          FRAMEBUFFER_NODE *pFramebuffer,
-                                          VkAttachmentReference ref)
-{
+static void TransitionAttachmentRefLayout(layer_data *dev_data, GLOBAL_CB_NODE *pCB, FRAMEBUFFER_STATE *pFramebuffer,
+                                          VkAttachmentReference ref) {
     if (ref.attachment != VK_ATTACHMENT_UNUSED) {
         auto image_view = pFramebuffer->createInfo.pAttachments[ref.attachment];
         SetLayout(dev_data, pCB, image_view, ref.layout);
@@ -10001,15 +10306,15 @@
 
 static void TransitionSubpassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin,
                                      const int subpass_index) {
-    auto renderPass = getRenderPass(dev_data, pRenderPassBegin->renderPass);
+    auto renderPass = getRenderPassState(dev_data, pRenderPassBegin->renderPass);
     if (!renderPass)
         return;
 
-    auto framebuffer = getFramebuffer(dev_data, pRenderPassBegin->framebuffer);
+    auto framebuffer = getFramebufferState(dev_data, pRenderPassBegin->framebuffer);
     if (!framebuffer)
         return;
 
-    const VkSubpassDescription &subpass = renderPass->pCreateInfo->pSubpasses[subpass_index];
+    auto const &subpass = renderPass->createInfo.pSubpasses[subpass_index];
     for (uint32_t j = 0; j < subpass.inputAttachmentCount; ++j) {
         TransitionAttachmentRefLayout(dev_data, pCB, framebuffer, subpass.pInputAttachments[j]);
     }
@@ -10021,10 +10326,10 @@
     }
 }
 
-static bool validatePrimaryCommandBuffer(const layer_data *my_data, const GLOBAL_CB_NODE *pCB, const std::string &cmd_name) {
+static bool validatePrimaryCommandBuffer(const layer_data *dev_data, const GLOBAL_CB_NODE *pCB, const std::string &cmd_name) {
     bool skip_call = false;
     if (pCB->createInfo.level != VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
-        skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                              DRAWSTATE_INVALID_COMMAND_BUFFER, "DS", "Cannot execute command %s on a secondary command buffer.",
                              cmd_name.c_str());
     }
@@ -10032,12 +10337,12 @@
 }
 
 static void TransitionFinalSubpassLayouts(layer_data *dev_data, GLOBAL_CB_NODE *pCB, const VkRenderPassBeginInfo *pRenderPassBegin) {
-    auto renderPass = getRenderPass(dev_data, pRenderPassBegin->renderPass);
+    auto renderPass = getRenderPassState(dev_data, pRenderPassBegin->renderPass);
     if (!renderPass)
         return;
 
-    const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->pCreateInfo;
-    auto framebuffer = getFramebuffer(dev_data, pRenderPassBegin->framebuffer);
+    const VkRenderPassCreateInfo *pRenderPassInfo = renderPass->createInfo.ptr();
+    auto framebuffer = getFramebufferState(dev_data, pRenderPassBegin->framebuffer);
     if (!framebuffer)
         return;
 
@@ -10047,15 +10352,16 @@
     }
 }
 
-static bool VerifyRenderAreaBounds(const layer_data *my_data, const VkRenderPassBeginInfo *pRenderPassBegin) {
+static bool VerifyRenderAreaBounds(const layer_data *dev_data, const VkRenderPassBeginInfo *pRenderPassBegin) {
     bool skip_call = false;
-    const safe_VkFramebufferCreateInfo *pFramebufferInfo = &getFramebuffer(my_data, pRenderPassBegin->framebuffer)->createInfo;
+    const safe_VkFramebufferCreateInfo *pFramebufferInfo =
+        &getFramebufferState(dev_data, pRenderPassBegin->framebuffer)->createInfo;
     if (pRenderPassBegin->renderArea.offset.x < 0 ||
         (pRenderPassBegin->renderArea.offset.x + pRenderPassBegin->renderArea.extent.width) > pFramebufferInfo->width ||
         pRenderPassBegin->renderArea.offset.y < 0 ||
         (pRenderPassBegin->renderArea.offset.y + pRenderPassBegin->renderArea.extent.height) > pFramebufferInfo->height) {
         skip_call |= static_cast<bool>(log_msg(
-            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
+            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
             DRAWSTATE_INVALID_RENDER_AREA, "CORE",
             "Cannot execute a render pass with renderArea not within the bound of the "
             "framebuffer. RenderArea: x %d, y %d, width %d, height %d. Framebuffer: width %d, "
@@ -10086,44 +10392,44 @@
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     GLOBAL_CB_NODE *cb_node = getCBNode(dev_data, commandBuffer);
-    auto renderPass = pRenderPassBegin ? getRenderPass(dev_data, pRenderPassBegin->renderPass) : nullptr;
-    auto framebuffer = pRenderPassBegin ? getFramebuffer(dev_data, pRenderPassBegin->framebuffer) : nullptr;
+    auto renderPass = pRenderPassBegin ? getRenderPassState(dev_data, pRenderPassBegin->renderPass) : nullptr;
+    auto framebuffer = pRenderPassBegin ? getFramebufferState(dev_data, pRenderPassBegin->framebuffer) : nullptr;
     if (cb_node) {
         if (renderPass) {
             uint32_t clear_op_size = 0; // Make sure pClearValues is at least as large as last LOAD_OP_CLEAR
             cb_node->activeFramebuffer = pRenderPassBegin->framebuffer;
-            for (size_t i = 0; i < renderPass->attachments.size(); ++i) {
+            for (uint32_t i = 0; i < renderPass->createInfo.attachmentCount; ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                VkFormat format = renderPass->pCreateInfo->pAttachments[renderPass->attachments[i].attachment].format;
-                if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
-                                                         renderPass->attachments[i].stencil_load_op,
+                auto pAttachment = &renderPass->createInfo.pAttachments[i];
+                if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
+                                                         pAttachment->stencilLoadOp,
                                                          VK_ATTACHMENT_LOAD_OP_CLEAR)) {
                     clear_op_size = static_cast<uint32_t>(i) + 1;
                     std::function<bool()> function = [=]() {
-                        SetImageMemoryValid(dev_data, getImageNode(dev_data, fb_info.image), true);
+                        SetImageMemoryValid(dev_data, getImageState(dev_data, fb_info.image), true);
                         return false;
                     };
                     cb_node->validate_functions.push_back(function);
-                } else if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
-                                                                renderPass->attachments[i].stencil_load_op,
+                } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
+                                                                pAttachment->stencilLoadOp,
                                                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE)) {
                     std::function<bool()> function = [=]() {
-                        SetImageMemoryValid(dev_data, getImageNode(dev_data, fb_info.image), false);
+                        SetImageMemoryValid(dev_data, getImageState(dev_data, fb_info.image), false);
                         return false;
                     };
                     cb_node->validate_functions.push_back(function);
-                } else if (FormatSpecificLoadAndStoreOpSettings(format, renderPass->attachments[i].load_op,
-                                                                renderPass->attachments[i].stencil_load_op,
+                } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->loadOp,
+                                                                pAttachment->stencilLoadOp,
                                                                 VK_ATTACHMENT_LOAD_OP_LOAD)) {
                     std::function<bool()> function = [=]() {
-                        return ValidateImageMemoryIsValid(dev_data, getImageNode(dev_data, fb_info.image),
+                        return ValidateImageMemoryIsValid(dev_data, getImageState(dev_data, fb_info.image),
                                                           "vkCmdBeginRenderPass()");
                     };
                     cb_node->validate_functions.push_back(function);
                 }
-                if (renderPass->attachment_first_read[renderPass->attachments[i].attachment]) {
+                if (renderPass->attachment_first_read[i]) {
                     std::function<bool()> function = [=]() {
-                        return ValidateImageMemoryIsValid(dev_data, getImageNode(dev_data, fb_info.image),
+                        return ValidateImageMemoryIsValid(dev_data, getImageState(dev_data, fb_info.image),
                                                           "vkCmdBeginRenderPass()");
                     };
                     cb_node->validate_functions.push_back(function);
@@ -10132,15 +10438,15 @@
             if (clear_op_size > pRenderPassBegin->clearValueCount) {
                 skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT,
-                            reinterpret_cast<uint64_t &>(renderPass), __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
+                            reinterpret_cast<uint64_t &>(renderPass), __LINE__, VALIDATION_ERROR_00442, "DS",
                             "In vkCmdBeginRenderPass() the VkRenderPassBeginInfo struct has a clearValueCount of %u but there must "
                             "be at least %u "
                             "entries in pClearValues array to account for the highest index attachment in renderPass 0x%" PRIx64
                             " that uses VK_ATTACHMENT_LOAD_OP_CLEAR is %u. Note that the pClearValues array "
                             "is indexed by attachment number so even if some pClearValues entries between 0 and %u correspond to "
-                            "attachments that aren't cleared they will be ignored.",
+                            "attachments that aren't cleared they will be ignored. %s",
                             pRenderPassBegin->clearValueCount, clear_op_size, reinterpret_cast<uint64_t &>(renderPass),
-                            clear_op_size, clear_op_size - 1);
+                            clear_op_size, clear_op_size - 1, validation_error_map[VALIDATION_ERROR_00442]);
             }
             skip_call |= VerifyRenderAreaBounds(dev_data, pRenderPassBegin);
             skip_call |= VerifyFramebufferAndRenderPassLayouts(dev_data, cb_node, pRenderPassBegin);
@@ -10154,16 +10460,8 @@
             cb_node->activeSubpass = 0;
             cb_node->activeSubpassContents = contents;
             cb_node->framebuffers.insert(pRenderPassBegin->framebuffer);
-            // Connect this framebuffer to this cmdBuffer
-            framebuffer->cb_bindings.insert(cb_node);
-            for (auto attach : framebuffer->attachments) {
-                auto img_node = getImageNode(dev_data, attach.image);
-                if (img_node) {
-                    addCommandBufferBinding(&img_node->cb_bindings,
-                                            {reinterpret_cast<uint64_t &>(attach.image), VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT},
-                                            cb_node);
-                }
-            }
+            // Connect this framebuffer and its children to this cmdBuffer
+            AddFramebufferBinding(dev_data, cb_node, framebuffer);
             // transition attachments to the correct layouts for the first subpass
             TransitionSubpassLayouts(dev_data, cb_node, &cb_node->activeRenderPassBeginInfo, cb_node->activeSubpass);
         } else {
@@ -10174,7 +10472,7 @@
     }
     lock.unlock();
     if (!skip_call) {
-        dev_data->device_dispatch_table->CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
+        dev_data->dispatch_table.CmdBeginRenderPass(commandBuffer, pRenderPassBegin, contents);
     }
 }
 
@@ -10188,7 +10486,7 @@
         skip_call |= addCmd(dev_data, pCB, CMD_NEXTSUBPASS, "vkCmdNextSubpass()");
         skip_call |= outsideRenderPass(dev_data, pCB, "vkCmdNextSubpass");
 
-        auto subpassCount = pCB->activeRenderPass->pCreateInfo->subpassCount;
+        auto subpassCount = pCB->activeRenderPass->createInfo.subpassCount;
         if (pCB->activeSubpass == subpassCount - 1) {
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
@@ -10201,7 +10499,7 @@
     if (skip_call)
         return;
 
-    dev_data->device_dispatch_table->CmdNextSubpass(commandBuffer, contents);
+    dev_data->dispatch_table.CmdNextSubpass(commandBuffer, contents);
 
     if (pCB) {
       lock.lock();
@@ -10217,31 +10515,31 @@
     std::unique_lock<std::mutex> lock(global_lock);
     auto pCB = getCBNode(dev_data, commandBuffer);
     if (pCB) {
-        RENDER_PASS_NODE* pRPNode = pCB->activeRenderPass;
-        auto framebuffer = getFramebuffer(dev_data, pCB->activeFramebuffer);
-        if (pRPNode) {
-            if (pCB->activeSubpass != pRPNode->pCreateInfo->subpassCount - 1) {
+        RENDER_PASS_STATE *rp_state = pCB->activeRenderPass;
+        auto framebuffer = getFramebufferState(dev_data, pCB->activeFramebuffer);
+        if (rp_state) {
+            if (pCB->activeSubpass != rp_state->createInfo.subpassCount - 1) {
                 skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(commandBuffer), __LINE__, DRAWSTATE_INVALID_SUBPASS_INDEX, "DS",
                             "vkCmdEndRenderPass(): Called before reaching final subpass");
             }
 
-            for (size_t i = 0; i < pRPNode->attachments.size(); ++i) {
+            for (size_t i = 0; i < rp_state->createInfo.attachmentCount; ++i) {
                 MT_FB_ATTACHMENT_INFO &fb_info = framebuffer->attachments[i];
-                VkFormat format = pRPNode->pCreateInfo->pAttachments[pRPNode->attachments[i].attachment].format;
-                if (FormatSpecificLoadAndStoreOpSettings(format, pRPNode->attachments[i].store_op,
-                                                         pRPNode->attachments[i].stencil_store_op, VK_ATTACHMENT_STORE_OP_STORE)) {
+                auto pAttachment = &rp_state->createInfo.pAttachments[i];
+                if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp,
+                                                         pAttachment->stencilStoreOp, VK_ATTACHMENT_STORE_OP_STORE)) {
                     std::function<bool()> function = [=]() {
-                        SetImageMemoryValid(dev_data, getImageNode(dev_data, fb_info.image), true);
+                        SetImageMemoryValid(dev_data, getImageState(dev_data, fb_info.image), true);
                         return false;
                     };
                     pCB->validate_functions.push_back(function);
-                } else if (FormatSpecificLoadAndStoreOpSettings(format, pRPNode->attachments[i].store_op,
-                                                                pRPNode->attachments[i].stencil_store_op,
+                } else if (FormatSpecificLoadAndStoreOpSettings(pAttachment->format, pAttachment->storeOp,
+                                                                pAttachment->stencilStoreOp,
                                                                 VK_ATTACHMENT_STORE_OP_DONT_CARE)) {
                     std::function<bool()> function = [=]() {
-                        SetImageMemoryValid(dev_data, getImageNode(dev_data, fb_info.image), false);
+                        SetImageMemoryValid(dev_data, getImageState(dev_data, fb_info.image), false);
                         return false;
                     };
                     pCB->validate_functions.push_back(function);
@@ -10257,7 +10555,7 @@
     if (skip_call)
         return;
 
-    dev_data->device_dispatch_table->CmdEndRenderPass(commandBuffer);
+    dev_data->dispatch_table.CmdEndRenderPass(commandBuffer);
 
     if (pCB) {
         lock.lock();
@@ -10405,13 +10703,13 @@
         if (primary_fb != secondary_fb) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
                                  DRAWSTATE_FRAMEBUFFER_INCOMPATIBLE, "DS",
-                                 "vkCmdExecuteCommands() called w/ invalid secondary Cmd Buffer 0x%" PRIx64
+                                 "vkCmdExecuteCommands() called w/ invalid secondary command buffer 0x%" PRIx64
                                  " which has a framebuffer 0x%" PRIx64
-                                 " that is not the same as the primaryCB's current active framebuffer 0x%" PRIx64 ".",
+                                 " that is not the same as the primary command buffer's current active framebuffer 0x%" PRIx64 ".",
                                  reinterpret_cast<uint64_t &>(secondaryBuffer), reinterpret_cast<uint64_t &>(secondary_fb),
                                  reinterpret_cast<uint64_t &>(primary_fb));
         }
-        auto fb = getFramebuffer(dev_data, secondary_fb);
+        auto fb = getFramebufferState(dev_data, secondary_fb);
         if (!fb) {
             skip_call |=
                 log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, 0, __LINE__,
@@ -10420,10 +10718,10 @@
                         (void *)secondaryBuffer, (uint64_t)(secondary_fb));
             return skip_call;
         }
-        auto cb_renderpass = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
+        auto cb_renderpass = getRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
         if (cb_renderpass->renderPass != fb->createInfo.renderPass) {
             skip_call |= validateRenderPassCompatibility(dev_data, secondaryBuffer, fb->renderPassCreateInfo.ptr(), secondaryBuffer,
-                                                         cb_renderpass->pCreateInfo);
+                                                         cb_renderpass->createInfo.ptr());
         }
     }
     return skip_call;
@@ -10502,7 +10800,7 @@
                                      "array. All cmd buffers in pCommandBuffers array must be secondary.",
                                      (void *)pCommandBuffers[i], i);
             } else if (pCB->activeRenderPass) { // Secondary CB w/i RenderPass must have *CONTINUE_BIT set
-                auto secondary_rp_node = getRenderPass(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
+                auto secondary_rp_state = getRenderPassState(dev_data, pSubCB->beginInfo.pInheritanceInfo->renderPass);
                 if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
@@ -10512,18 +10810,19 @@
                         (void *)pCommandBuffers[i], (uint64_t)pCB->activeRenderPass->renderPass);
                 } else {
                     // Make sure render pass is compatible with parent command buffer pass if has continue
-                    if (pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) {
-                        skip_call |= validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->pCreateInfo,
-                                                                    pCommandBuffers[i], secondary_rp_node->pCreateInfo);
+                    if (pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) {
+                        skip_call |=
+                            validateRenderPassCompatibility(dev_data, commandBuffer, pCB->activeRenderPass->createInfo.ptr(),
+                                                            pCommandBuffers[i], secondary_rp_state->createInfo.ptr());
                     }
                     //  If framebuffer for secondary CB is not NULL, then it must match active FB from primaryCB
                     skip_call |= validateFramebuffer(dev_data, commandBuffer, pCB, pCommandBuffers[i], pSubCB);
                 }
                 string errorString = "";
                 // secondaryCB must have been created w/ RP compatible w/ primaryCB active renderpass
-                if ((pCB->activeRenderPass->renderPass != secondary_rp_node->renderPass) &&
-                    !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->pCreateInfo, secondary_rp_node->pCreateInfo,
-                                                     errorString)) {
+                if ((pCB->activeRenderPass->renderPass != secondary_rp_state->renderPass) &&
+                    !verify_renderpass_compatibility(dev_data, pCB->activeRenderPass->createInfo.ptr(),
+                                                     secondary_rp_state->createInfo.ptr(), errorString)) {
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)pCommandBuffers[i], __LINE__, DRAWSTATE_RENDERPASS_INCOMPATIBLE, "DS",
@@ -10535,7 +10834,7 @@
             }
             // TODO(mlentine): Move more logic into this method
             skip_call |= validateSecondaryCommandBufferState(dev_data, pCB, pSubCB);
-            skip_call |= validateCommandBufferState(dev_data, pSubCB);
+            skip_call |= validateCommandBufferState(dev_data, pSubCB, "vkCmdExecuteCommands()");
             // Secondary cmdBuffers are considered pending execution starting w/
             // being recorded
             if (!(pSubCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) {
@@ -10543,8 +10842,8 @@
                     skip_call |= log_msg(
                         dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                         (uint64_t)(pCB->commandBuffer), __LINE__, DRAWSTATE_INVALID_CB_SIMULTANEOUS_USE, "DS",
-                        "Attempt to simultaneously execute CB 0x%" PRIxLEAST64 " w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT "
-                        "set!",
+                        "Attempt to simultaneously execute command buffer 0x%" PRIxLEAST64
+                        " without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!",
                         (uint64_t)(pCB->commandBuffer));
                 }
                 if (pCB->beginInfo.flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT) {
@@ -10560,7 +10859,7 @@
                     pCB->beginInfo.flags &= ~VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
                 }
             }
-            if (!pCB->activeQueries.empty() && !dev_data->phys_dev_properties.features.inheritedQueries) {
+            if (!pCB->activeQueries.empty() && !dev_data->enabled_features.inheritedQueries) {
                 skip_call |=
                     log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
                             reinterpret_cast<uint64_t>(pCommandBuffers[i]), __LINE__, DRAWSTATE_INVALID_COMMAND_BUFFER, "DS",
@@ -10582,7 +10881,7 @@
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
+        dev_data->dispatch_table.CmdExecuteCommands(commandBuffer, commandBuffersCount, pCommandBuffers);
 }
 
 // For any image objects that overlap mapped memory, verify that their layouts are PREINIT or GENERAL
@@ -10642,7 +10941,7 @@
     lock.unlock();
 
     if (!skip_call) {
-        result = dev_data->device_dispatch_table->MapMemory(device, mem, offset, size, flags, ppData);
+        result = dev_data->dispatch_table.MapMemory(device, mem, offset, size, flags, ppData);
         if (VK_SUCCESS == result) {
             lock.lock();
             // TODO : What's the point of this range? See comment on creating new "bound_range" above, which may replace this
@@ -10655,63 +10954,64 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory mem) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     bool skip_call = false;
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= deleteMemRanges(my_data, mem);
+    skip_call |= deleteMemRanges(dev_data, mem);
     lock.unlock();
     if (!skip_call) {
-        my_data->device_dispatch_table->UnmapMemory(device, mem);
+        dev_data->dispatch_table.UnmapMemory(device, mem);
     }
 }
 
-static bool validateMemoryIsMapped(layer_data *my_data, const char *funcName, uint32_t memRangeCount,
+static bool validateMemoryIsMapped(layer_data *dev_data, const char *funcName, uint32_t memRangeCount,
                                    const VkMappedMemoryRange *pMemRanges) {
     bool skip_call = false;
     for (uint32_t i = 0; i < memRangeCount; ++i) {
-        auto mem_info = getMemObjInfo(my_data, pMemRanges[i].memory);
+        auto mem_info = getMemObjInfo(dev_data, pMemRanges[i].memory);
         if (mem_info) {
             if (mem_info->mem_range.offset > pMemRanges[i].offset) {
                 skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                             (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
                             "%s: Flush/Invalidate offset (" PRINTF_SIZE_T_SPECIFIER ") is less than Memory Object's offset "
                             "(" PRINTF_SIZE_T_SPECIFIER ").",
                             funcName, static_cast<size_t>(pMemRanges[i].offset), static_cast<size_t>(mem_info->mem_range.offset));
             }
 
-            const uint64_t my_dataTerminus = (mem_info->mem_range.size == VK_WHOLE_SIZE)
-                                                 ? mem_info->alloc_info.allocationSize
-                                                 : (mem_info->mem_range.offset + mem_info->mem_range.size);
-            if (pMemRanges[i].size != VK_WHOLE_SIZE && (my_dataTerminus < (pMemRanges[i].offset + pMemRanges[i].size))) {
-                skip_call |= log_msg(
-                    my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
-                    (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
-                    "%s: Flush/Invalidate upper-bound (" PRINTF_SIZE_T_SPECIFIER ") exceeds the Memory Object's upper-bound "
-                    "(" PRINTF_SIZE_T_SPECIFIER ").",
-                    funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size), static_cast<size_t>(my_dataTerminus));
+            const uint64_t dev_dataTerminus = (mem_info->mem_range.size == VK_WHOLE_SIZE)
+                                                  ? mem_info->alloc_info.allocationSize
+                                                  : (mem_info->mem_range.offset + mem_info->mem_range.size);
+            if (pMemRanges[i].size != VK_WHOLE_SIZE && (dev_dataTerminus < (pMemRanges[i].offset + pMemRanges[i].size))) {
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                     VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, (uint64_t)pMemRanges[i].memory, __LINE__,
+                                     MEMTRACK_INVALID_MAP, "MEM", "%s: Flush/Invalidate upper-bound (" PRINTF_SIZE_T_SPECIFIER
+                                                                  ") exceeds the Memory Object's upper-bound "
+                                                                  "(" PRINTF_SIZE_T_SPECIFIER ").",
+                                     funcName, static_cast<size_t>(pMemRanges[i].offset + pMemRanges[i].size),
+                                     static_cast<size_t>(dev_dataTerminus));
             }
         }
     }
     return skip_call;
 }
 
-static bool ValidateAndCopyNoncoherentMemoryToDriver(layer_data *my_data, uint32_t memRangeCount,
+static bool ValidateAndCopyNoncoherentMemoryToDriver(layer_data *dev_data, uint32_t memRangeCount,
                                                      const VkMappedMemoryRange *pMemRanges) {
     bool skip_call = false;
     for (uint32_t i = 0; i < memRangeCount; ++i) {
-        auto mem_info = getMemObjInfo(my_data, pMemRanges[i].memory);
+        auto mem_info = getMemObjInfo(dev_data, pMemRanges[i].memory);
         if (mem_info) {
             if (mem_info->shadow_copy) {
                 VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE)
                                         ? mem_info->mem_range.size
-                                        : (mem_info->alloc_info.allocationSize - pMemRanges[i].offset);
+                                        : (mem_info->alloc_info.allocationSize - mem_info->mem_range.offset);
                 char *data = static_cast<char *>(mem_info->shadow_copy);
                 for (uint64_t j = 0; j < mem_info->shadow_pad_size; ++j) {
                     if (data[j] != NoncoherentMemoryFillValue) {
                         skip_call |= log_msg(
-                            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                             (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
                             "Memory underflow was detected on mem obj 0x%" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
                     }
@@ -10719,7 +11019,7 @@
                 for (uint64_t j = (size + mem_info->shadow_pad_size); j < (2 * mem_info->shadow_pad_size + size); ++j) {
                     if (data[j] != NoncoherentMemoryFillValue) {
                         skip_call |= log_msg(
-                            my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                            dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
                             (uint64_t)pMemRanges[i].memory, __LINE__, MEMTRACK_INVALID_MAP, "MEM",
                             "Memory overflow was detected on mem obj 0x%" PRIxLEAST64, (uint64_t)pMemRanges[i].memory);
                     }
@@ -10731,10 +11031,10 @@
     return skip_call;
 }
 
-static void CopyNoncoherentMemoryFromDriver(layer_data *my_data, uint32_t memory_range_count,
+static void CopyNoncoherentMemoryFromDriver(layer_data *dev_data, uint32_t memory_range_count,
                                             const VkMappedMemoryRange *mem_ranges) {
     for (uint32_t i = 0; i < memory_range_count; ++i) {
-        auto mem_info = getMemObjInfo(my_data, mem_ranges[i].memory);
+        auto mem_info = getMemObjInfo(dev_data, mem_ranges[i].memory);
         if (mem_info && mem_info->shadow_copy) {
             VkDeviceSize size = (mem_info->mem_range.size != VK_WHOLE_SIZE)
                                     ? mem_info->mem_range.size
@@ -10745,35 +11045,35 @@
     }
 }
 
-VkResult VKAPI_CALL
+VKAPI_ATTR VkResult VKAPI_CALL
 FlushMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange *pMemRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateAndCopyNoncoherentMemoryToDriver(my_data, memRangeCount, pMemRanges);
-    skip_call |= validateMemoryIsMapped(my_data, "vkFlushMappedMemoryRanges", memRangeCount, pMemRanges);
+    skip_call |= ValidateAndCopyNoncoherentMemoryToDriver(dev_data, memRangeCount, pMemRanges);
+    skip_call |= validateMemoryIsMapped(dev_data, "vkFlushMappedMemoryRanges", memRangeCount, pMemRanges);
     lock.unlock();
     if (!skip_call) {
-        result = my_data->device_dispatch_table->FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
+        result = dev_data->dispatch_table.FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
     }
     return result;
 }
 
-VkResult VKAPI_CALL
+VKAPI_ATTR VkResult VKAPI_CALL
 InvalidateMappedMemoryRanges(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange *pMemRanges) {
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
 
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= validateMemoryIsMapped(my_data, "vkInvalidateMappedMemoryRanges", memRangeCount, pMemRanges);
+    skip_call |= validateMemoryIsMapped(dev_data, "vkInvalidateMappedMemoryRanges", memRangeCount, pMemRanges);
     lock.unlock();
     if (!skip_call) {
-        result = my_data->device_dispatch_table->InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
+        result = dev_data->dispatch_table.InvalidateMappedMemoryRanges(device, memRangeCount, pMemRanges);
         // Update our shadow copy with modified driver data
-        CopyNoncoherentMemoryFromDriver(my_data, memRangeCount, pMemRanges);
+        CopyNoncoherentMemoryFromDriver(dev_data, memRangeCount, pMemRanges);
     }
     return result;
 }
@@ -10783,32 +11083,32 @@
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    auto image_node = getImageNode(dev_data, image);
-    if (image_node) {
+    auto image_state = getImageState(dev_data, image);
+    if (image_state) {
         // Track objects tied to memory
         uint64_t image_handle = reinterpret_cast<uint64_t &>(image);
-        skip_call = set_mem_binding(dev_data, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory");
+        skip_call = SetMemBinding(dev_data, mem, image_handle, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, "vkBindImageMemory");
         VkMemoryRequirements memRequirements;
         lock.unlock();
-        dev_data->device_dispatch_table->GetImageMemoryRequirements(device, image, &memRequirements);
+        dev_data->dispatch_table.GetImageMemoryRequirements(device, image, &memRequirements);
         lock.lock();
 
         // Track and validate bound memory range information
         auto mem_info = getMemObjInfo(dev_data, mem);
         if (mem_info) {
             skip_call |= InsertImageMemoryRange(dev_data, image, mem_info, memoryOffset, memRequirements,
-                                                image_node->createInfo.tiling == VK_IMAGE_TILING_LINEAR);
+                                                image_state->createInfo.tiling == VK_IMAGE_TILING_LINEAR);
             skip_call |= ValidateMemoryTypes(dev_data, mem_info, memRequirements.memoryTypeBits, "vkBindImageMemory");
         }
 
         print_mem_list(dev_data);
         lock.unlock();
         if (!skip_call) {
-            result = dev_data->device_dispatch_table->BindImageMemory(device, image, mem, memoryOffset);
+            result = dev_data->dispatch_table.BindImageMemory(device, image, mem, memoryOffset);
             lock.lock();
-            image_node->mem = mem;
-            image_node->memOffset = memoryOffset;
-            image_node->memSize = memRequirements.size;
+            image_state->binding.mem = mem;
+            image_state->binding.offset = memoryOffset;
+            image_state->binding.size = memRequirements.size;
             lock.unlock();
         }
     } else {
@@ -10825,11 +11125,11 @@
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    auto event_node = getEventNode(dev_data, event);
-    if (event_node) {
-        event_node->needsSignaled = false;
-        event_node->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
-        if (event_node->write_in_use) {
+    auto event_state = getEventNode(dev_data, event);
+    if (event_state) {
+        event_state->needsSignaled = false;
+        event_state->stageMask = VK_PIPELINE_STAGE_HOST_BIT;
+        if (event_state->write_in_use) {
             skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT,
                                  reinterpret_cast<const uint64_t &>(event), __LINE__, DRAWSTATE_QUEUE_FORWARD_PROGRESS, "DS",
                                  "Cannot call vkSetEvent() on event 0x%" PRIxLEAST64 " that is already in use by a command buffer.",
@@ -10847,7 +11147,7 @@
         }
     }
     if (!skip_call)
-        result = dev_data->device_dispatch_table->SetEvent(device, event);
+        result = dev_data->dispatch_table.SetEvent(device, event);
     return result;
 }
 
@@ -10872,25 +11172,30 @@
         // Track objects tied to memory
         for (uint32_t j = 0; j < bindInfo.bufferBindCount; j++) {
             for (uint32_t k = 0; k < bindInfo.pBufferBinds[j].bindCount; k++) {
-                if (set_sparse_mem_binding(dev_data, bindInfo.pBufferBinds[j].pBinds[k].memory,
-                                           (uint64_t)bindInfo.pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
-                                           "vkQueueBindSparse"))
+                auto sparse_binding = bindInfo.pBufferBinds[j].pBinds[k];
+                if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size},
+                                        (uint64_t)bindInfo.pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+                                        "vkQueueBindSparse"))
                     skip_call = true;
             }
         }
         for (uint32_t j = 0; j < bindInfo.imageOpaqueBindCount; j++) {
             for (uint32_t k = 0; k < bindInfo.pImageOpaqueBinds[j].bindCount; k++) {
-                if (set_sparse_mem_binding(dev_data, bindInfo.pImageOpaqueBinds[j].pBinds[k].memory,
-                                           (uint64_t)bindInfo.pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
-                                           "vkQueueBindSparse"))
+                auto sparse_binding = bindInfo.pImageOpaqueBinds[j].pBinds[k];
+                if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, sparse_binding.size},
+                                        (uint64_t)bindInfo.pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                        "vkQueueBindSparse"))
                     skip_call = true;
             }
         }
         for (uint32_t j = 0; j < bindInfo.imageBindCount; j++) {
             for (uint32_t k = 0; k < bindInfo.pImageBinds[j].bindCount; k++) {
-                if (set_sparse_mem_binding(dev_data, bindInfo.pImageBinds[j].pBinds[k].memory,
-                                           (uint64_t)bindInfo.pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
-                                           "vkQueueBindSparse"))
+                auto sparse_binding = bindInfo.pImageBinds[j].pBinds[k];
+                // TODO: This size is broken for non-opaque bindings, need to update to comprehend full sparse binding data
+                VkDeviceSize size = sparse_binding.extent.depth * sparse_binding.extent.height * sparse_binding.extent.width * 4;
+                if (SetSparseMemBinding(dev_data, {sparse_binding.memory, sparse_binding.memoryOffset, size},
+                                        (uint64_t)bindInfo.pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+                                        "vkQueueBindSparse"))
                     skip_call = true;
             }
         }
@@ -10958,7 +11263,7 @@
     lock.unlock();
 
     if (!skip_call)
-        return dev_data->device_dispatch_table->QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
+        return dev_data->dispatch_table.QueueBindSparse(queue, bindInfoCount, pBindInfo, fence);
 
     return result;
 }
@@ -10966,7 +11271,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo *pCreateInfo,
                                                const VkAllocationCallbacks *pAllocator, VkSemaphore *pSemaphore) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
+    VkResult result = dev_data->dispatch_table.CreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore);
     if (result == VK_SUCCESS) {
         std::lock_guard<std::mutex> lock(global_lock);
         SEMAPHORE_NODE* sNode = &dev_data->semaphoreMap[*pSemaphore];
@@ -10980,7 +11285,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateEvent(VkDevice device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateEvent(device, pCreateInfo, pAllocator, pEvent);
+    VkResult result = dev_data->dispatch_table.CreateEvent(device, pCreateInfo, pAllocator, pEvent);
     if (result == VK_SUCCESS) {
         std::lock_guard<std::mutex> lock(global_lock);
         dev_data->eventMap[*pEvent].needsSignaled = false;
@@ -10990,17 +11295,50 @@
     return result;
 }
 
+static bool PreCallValidateCreateSwapchainKHR(layer_data *dev_data, VkSwapchainCreateInfoKHR const *pCreateInfo,
+                                              SURFACE_STATE *surface_state, SWAPCHAIN_NODE *old_swapchain_state) {
+    auto most_recent_swapchain = surface_state->swapchain ? surface_state->swapchain : surface_state->old_swapchain;
+
+    if (most_recent_swapchain != old_swapchain_state || (surface_state->old_swapchain && surface_state->swapchain)) {
+        if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+                    reinterpret_cast<uint64_t>(dev_data->device), __LINE__, DRAWSTATE_SWAPCHAIN_ALREADY_EXISTS, "DS",
+                    "vkCreateSwapchainKHR(): surface has an existing swapchain other than oldSwapchain"))
+            return true;
+    }
+    if (old_swapchain_state && old_swapchain_state->createInfo.surface != pCreateInfo->surface) {
+        if (log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+                    reinterpret_cast<uint64_t const &>(pCreateInfo->oldSwapchain), __LINE__, DRAWSTATE_SWAPCHAIN_WRONG_SURFACE,
+                    "DS", "vkCreateSwapchainKHR(): pCreateInfo->oldSwapchain's surface is not pCreateInfo->surface"))
+            return true;
+    }
+
+    return false;
+}
+
 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
                                                   const VkAllocationCallbacks *pAllocator,
                                                   VkSwapchainKHR *pSwapchain) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+    auto surface_state = getSurfaceState(dev_data->instance_data, pCreateInfo->surface);
+    auto old_swapchain_state = getSwapchainNode(dev_data, pCreateInfo->oldSwapchain);
+
+    if (PreCallValidateCreateSwapchainKHR(dev_data, pCreateInfo, surface_state, old_swapchain_state))
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+
+    VkResult result = dev_data->dispatch_table.CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
 
     if (VK_SUCCESS == result) {
         std::lock_guard<std::mutex> lock(global_lock);
-        dev_data->device_extensions.swapchainMap[*pSwapchain] = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(pCreateInfo));
+        auto swapchain_state = unique_ptr<SWAPCHAIN_NODE>(new SWAPCHAIN_NODE(pCreateInfo, *pSwapchain));
+        surface_state->swapchain = swapchain_state.get();
+        dev_data->device_extensions.swapchainMap[*pSwapchain] = std::move(swapchain_state);
+    } else {
+        surface_state->swapchain = nullptr;
     }
 
+    // Spec requires that even if CreateSwapchainKHR fails, oldSwapchain behaves as replaced.
+    surface_state->old_swapchain = old_swapchain_state;
+
     return result;
 }
 
@@ -11025,21 +11363,30 @@
                     dev_data->imageSubresourceMap.erase(image_sub);
                 }
                 skip_call =
-                    clear_object_binding(dev_data, (uint64_t)swapchain_image, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+                    ClearMemoryObjectBindings(dev_data, (uint64_t)swapchain_image, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
                 dev_data->imageMap.erase(swapchain_image);
             }
         }
+
+        auto surface_state = getSurfaceState(dev_data->instance_data, swapchain_data->createInfo.surface);
+        if (surface_state) {
+            if (surface_state->swapchain == swapchain_data)
+                surface_state->swapchain = nullptr;
+            if (surface_state->old_swapchain == swapchain_data)
+                surface_state->old_swapchain = nullptr;
+        }
+
         dev_data->device_extensions.swapchainMap.erase(swapchain);
     }
     lock.unlock();
     if (!skip_call)
-        dev_data->device_dispatch_table->DestroySwapchainKHR(device, swapchain, pAllocator);
+        dev_data->dispatch_table.DestroySwapchainKHR(device, swapchain, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
 GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pCount, VkImage *pSwapchainImages) {
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkResult result = dev_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
+    VkResult result = dev_data->dispatch_table.GetSwapchainImagesKHR(device, swapchain, pCount, pSwapchainImages);
 
     if (result == VK_SUCCESS && pSwapchainImages != NULL) {
         // This should never happen and is checked by param checker.
@@ -11075,10 +11422,10 @@
             image_ci.extent.width = swapchain_node->createInfo.imageExtent.width;
             image_ci.extent.height = swapchain_node->createInfo.imageExtent.height;
             image_ci.sharingMode = swapchain_node->createInfo.imageSharingMode;
-            dev_data->imageMap[pSwapchainImages[i]] = unique_ptr<IMAGE_NODE>(new IMAGE_NODE(pSwapchainImages[i], &image_ci));
-            auto &image_node = dev_data->imageMap[pSwapchainImages[i]];
-            image_node->valid = false;
-            image_node->mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
+            dev_data->imageMap[pSwapchainImages[i]] = unique_ptr<IMAGE_STATE>(new IMAGE_STATE(pSwapchainImages[i], &image_ci));
+            auto &image_state = dev_data->imageMap[pSwapchainImages[i]];
+            image_state->valid = false;
+            image_state->binding.mem = MEMTRACKER_SWAP_CHAIN_IMAGE_KEY;
             swapchain_node->images.push_back(pSwapchainImages[i]);
             ImageSubresourcePair subpair = {pSwapchainImages[i], false, VkImageSubresource()};
             dev_data->imageSubresourceMap[pSwapchainImages[i]].push_back(subpair);
@@ -11107,19 +11454,36 @@
 
     for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
         auto swapchain_data = getSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]);
-        if (swapchain_data && pPresentInfo->pImageIndices[i] < swapchain_data->images.size()) {
-            VkImage image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
-            skip_call |= ValidateImageMemoryIsValid(dev_data, getImageNode(dev_data, image), "vkQueuePresentKHR()");
-            vector<VkImageLayout> layouts;
-            if (FindLayouts(dev_data, image, layouts)) {
-                for (auto layout : layouts) {
-                    if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
-                        skip_call |=
-                                log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
-                                        reinterpret_cast<uint64_t &>(queue), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
-                                        "Images passed to present must be in layout "
-                                        "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR but is in %s",
-                                        string_VkImageLayout(layout));
+        if (swapchain_data) {
+            if (pPresentInfo->pImageIndices[i] >= swapchain_data->images.size()) {
+                skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+                                     reinterpret_cast<uint64_t const &>(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_INVALID_IMAGE,
+                                     "DS", "vkQueuePresentKHR: Swapchain image index too large (%u). There are only %u images in this swapchain.",
+                                     pPresentInfo->pImageIndices[i], (uint32_t)swapchain_data->images.size());
+            }
+            else {
+                auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
+                auto image_state = getImageState(dev_data, image);
+                skip_call |= ValidateImageMemoryIsValid(dev_data, image_state, "vkQueuePresentKHR()");
+
+                if (!image_state->acquired) {
+                    skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
+                                         reinterpret_cast<uint64_t const &>(pPresentInfo->pSwapchains[i]), __LINE__, DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED,
+                                         "DS", "vkQueuePresentKHR: Swapchain image index %u has not been acquired.",
+                                         pPresentInfo->pImageIndices[i]);
+                }
+
+                vector<VkImageLayout> layouts;
+                if (FindLayouts(dev_data, image, layouts)) {
+                    for (auto layout : layouts) {
+                        if (layout != VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) {
+                            skip_call |=
+                                    log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT,
+                                            reinterpret_cast<uint64_t &>(queue), __LINE__, DRAWSTATE_INVALID_IMAGE_LAYOUT, "DS",
+                                            "Images passed to present must be in layout "
+                                            "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR but is in %s",
+                                            string_VkImageLayout(layout));
+                        }
                     }
                 }
             }
@@ -11130,7 +11494,7 @@
         return VK_ERROR_VALIDATION_FAILED_EXT;
     }
 
-    VkResult result = dev_data->device_dispatch_table->QueuePresentKHR(queue, pPresentInfo);
+    VkResult result = dev_data->dispatch_table.QueuePresentKHR(queue, pPresentInfo);
 
     if (result != VK_ERROR_VALIDATION_FAILED_EXT) {
         // Semaphore waits occur before error generation, if the call reached
@@ -11143,6 +11507,22 @@
             }
         }
 
+        for (uint32_t i = 0; i < pPresentInfo->swapchainCount; ++i) {
+            // Note: this is imperfect, in that we can get confused about what
+            // did or didn't succeed-- but if the app does that, it's confused
+            // itself just as much.
+            auto local_result = pPresentInfo->pResults ? pPresentInfo->pResults[i] : result;
+
+            if (local_result != VK_SUCCESS && local_result != VK_SUBOPTIMAL_KHR)
+                continue; // this present didn't actually happen.
+
+            // Mark the image as having been released to the WSI
+            auto swapchain_data = getSwapchainNode(dev_data, pPresentInfo->pSwapchains[i]);
+            auto image = swapchain_data->images[pPresentInfo->pImageIndices[i]];
+            auto image_state = getImageState(dev_data, image);
+            image_state->acquired = false;
+        }
+
         // Note: even though presentation is directed to a queue, there is no
         // direct ordering between QP and subsequent work, so QP (and its
         // semaphore waits) /never/ participate in any completion proof.
@@ -11157,7 +11537,7 @@
     layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
     VkResult result =
-        dev_data->device_dispatch_table->CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
+        dev_data->dispatch_table.CreateSharedSwapchainsKHR(device, swapchainCount, pCreateInfos, pAllocator, pSwapchains);
     return result;
 }
 
@@ -11167,6 +11547,14 @@
     bool skip_call = false;
 
     std::unique_lock<std::mutex> lock(global_lock);
+
+    if (fence == VK_NULL_HANDLE && semaphore == VK_NULL_HANDLE) {
+        skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
+                             reinterpret_cast<uint64_t &>(device), __LINE__, DRAWSTATE_SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, "DS",
+                             "vkAcquireNextImageKHR: Semaphore and fence cannot both be VK_NULL_HANDLE. There would be no way "
+                             "to determine the completion of this operation.");
+    }
+
     auto pSemaphore = getSemaphoreNode(dev_data, semaphore);
     if (pSemaphore && pSemaphore->signaled) {
         skip_call |= log_msg(dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT,
@@ -11183,8 +11571,7 @@
     if (skip_call)
         return VK_ERROR_VALIDATION_FAILED_EXT;
 
-    VkResult result =
-            dev_data->device_dispatch_table->AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
+    VkResult result = dev_data->dispatch_table.AcquireNextImageKHR(device, swapchain, timeout, semaphore, fence, pImageIndex);
 
     lock.lock();
     if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
@@ -11198,6 +11585,12 @@
             pSemaphore->signaled = true;
             pSemaphore->signaler.first = VK_NULL_HANDLE;
         }
+
+        // Mark the image as acquired.
+        auto swapchain_data = getSwapchainNode(dev_data, swapchain);
+        auto image = swapchain_data->images[*pImageIndex];
+        auto image_state = getImageState(dev_data, image);
+        image_state->acquired = true;
     }
     lock.unlock();
 
@@ -11207,49 +11600,48 @@
 VKAPI_ATTR VkResult VKAPI_CALL EnumeratePhysicalDevices(VkInstance instance, uint32_t *pPhysicalDeviceCount,
                                                         VkPhysicalDevice *pPhysicalDevices) {
     bool skip_call = false;
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    if (my_data->instance_state) {
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+
+    if (instance_data) {
         // For this instance, flag when vkEnumeratePhysicalDevices goes to QUERY_COUNT and then QUERY_DETAILS
         if (NULL == pPhysicalDevices) {
-            my_data->instance_state->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
+            instance_data->vkEnumeratePhysicalDevicesState = QUERY_COUNT;
         } else {
-            if (UNCALLED == my_data->instance_state->vkEnumeratePhysicalDevicesState) {
+            if (UNCALLED == instance_data->vkEnumeratePhysicalDevicesState) {
                 // Flag warning here. You can call this without having queried the count, but it may not be
                 // robust on platforms with multiple physical devices.
-                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
-                                    0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
-                                    "Call sequence has vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
-                                    "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
+                skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
+                                     0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
+                                     "Call sequence has vkEnumeratePhysicalDevices() w/ non-NULL pPhysicalDevices. You should first "
+                                     "call vkEnumeratePhysicalDevices() w/ NULL pPhysicalDevices to query pPhysicalDeviceCount.");
             } // TODO : Could also flag a warning if re-calling this function in QUERY_DETAILS state
-            else if (my_data->instance_state->physical_devices_count != *pPhysicalDeviceCount) {
+            else if (instance_data->physical_devices_count != *pPhysicalDeviceCount) {
                 // Having actual count match count from app is not a requirement, so this can be a warning
-                skip_call |= log_msg(my_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
-                                    "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
-                                    "supported by this instance is %u.",
-                                    *pPhysicalDeviceCount, my_data->instance_state->physical_devices_count);
+                skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                                     VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
+                                     "Call to vkEnumeratePhysicalDevices() w/ pPhysicalDeviceCount value %u, but actual count "
+                                     "supported by this instance is %u.",
+                                     *pPhysicalDeviceCount, instance_data->physical_devices_count);
             }
-            my_data->instance_state->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
+            instance_data->vkEnumeratePhysicalDevicesState = QUERY_DETAILS;
         }
         if (skip_call) {
             return VK_ERROR_VALIDATION_FAILED_EXT;
         }
-        VkResult result =
-            my_data->instance_dispatch_table->EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+        VkResult result = instance_data->dispatch_table.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
         if (NULL == pPhysicalDevices) {
-            my_data->instance_state->physical_devices_count = *pPhysicalDeviceCount;
+            instance_data->physical_devices_count = *pPhysicalDeviceCount;
         } else if (result == VK_SUCCESS){ // Save physical devices
             for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
-                layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(pPhysicalDevices[i]), layer_data_map);
-                phy_dev_data->physical_device_state = unique_ptr<PHYSICAL_DEVICE_STATE>(new PHYSICAL_DEVICE_STATE());
+                auto & phys_device_state = instance_data->physical_device_map[pPhysicalDevices[i]];
+                phys_device_state.phys_device = pPhysicalDevices[i];
                 // Init actual features for each physical device
-                my_data->instance_dispatch_table->GetPhysicalDeviceFeatures(pPhysicalDevices[i],
-                                                                            &phy_dev_data->physical_device_features);
+                instance_data->dispatch_table.GetPhysicalDeviceFeatures(pPhysicalDevices[i], &phys_device_state.features);
             }
         }
         return result;
     } else {
-        log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
+        log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, 0, __LINE__,
                 DEVLIMITS_INVALID_INSTANCE, "DL", "Invalid instance (0x%" PRIxLEAST64 ") passed into vkEnumeratePhysicalDevices().",
                 (uint64_t)instance);
     }
@@ -11260,67 +11652,146 @@
 GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
     VkQueueFamilyProperties *pQueueFamilyProperties) {
     bool skip_call = false;
-    layer_data *phy_dev_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    if (phy_dev_data->physical_device_state) {
-        if (NULL == pQueueFamilyProperties) {
-            phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map);
+    auto physical_device_state = getPhysicalDeviceState(instance_data, physicalDevice);
+    if (physical_device_state) {
+        if (!pQueueFamilyProperties) {
+            physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_COUNT;
         }
         else {
             // Verify that for each physical device, this function is called first with NULL pQueueFamilyProperties ptr in order to
             // get count
-            if (UNCALLED == phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
-                skip_call |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+            if (UNCALLED == physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState) {
+                skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
                     VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_MISSING_QUERY_COUNT, "DL",
                     "Call sequence has vkGetPhysicalDeviceQueueFamilyProperties() w/ non-NULL "
                     "pQueueFamilyProperties. You should first call vkGetPhysicalDeviceQueueFamilyProperties() w/ "
                     "NULL pQueueFamilyProperties to query pCount.");
             }
             // Then verify that pCount that is passed in on second call matches what was returned
-            if (phy_dev_data->physical_device_state->queueFamilyPropertiesCount != *pCount) {
+            if (physical_device_state->queueFamilyPropertiesCount != *pCount) {
 
                 // TODO: this is not a requirement of the Valid Usage section for vkGetPhysicalDeviceQueueFamilyProperties, so
                 // provide as warning
-                skip_call |= log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                skip_call |= log_msg(instance_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
                     VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0, __LINE__, DEVLIMITS_COUNT_MISMATCH, "DL",
                     "Call to vkGetPhysicalDeviceQueueFamilyProperties() w/ pCount value %u, but actual count "
                     "supported by this physicalDevice is %u.",
-                    *pCount, phy_dev_data->physical_device_state->queueFamilyPropertiesCount);
+                    *pCount, physical_device_state->queueFamilyPropertiesCount);
             }
-            phy_dev_data->physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
+            physical_device_state->vkGetPhysicalDeviceQueueFamilyPropertiesState = QUERY_DETAILS;
         }
         if (skip_call) {
             return;
         }
-        phy_dev_data->instance_dispatch_table->GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount,
-            pQueueFamilyProperties);
-        if (NULL == pQueueFamilyProperties) {
-            phy_dev_data->physical_device_state->queueFamilyPropertiesCount = *pCount;
+        instance_data->dispatch_table.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, pCount, pQueueFamilyProperties);
+        if (!pQueueFamilyProperties) {
+            physical_device_state->queueFamilyPropertiesCount = *pCount;
         }
         else { // Save queue family properties
-            phy_dev_data->queue_family_properties.reserve(*pCount);
+            if (physical_device_state->queue_family_properties.size() < *pCount)
+                physical_device_state->queue_family_properties.resize(*pCount);
             for (uint32_t i = 0; i < *pCount; i++) {
-                phy_dev_data->queue_family_properties.emplace_back(new VkQueueFamilyProperties(pQueueFamilyProperties[i]));
+                physical_device_state->queue_family_properties[i] = pQueueFamilyProperties[i];
             }
         }
-        return;
     }
     else {
-        log_msg(phy_dev_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
+        log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, 0,
             __LINE__, DEVLIMITS_INVALID_PHYSICAL_DEVICE, "DL",
             "Invalid physicalDevice (0x%" PRIxLEAST64 ") passed into vkGetPhysicalDeviceQueueFamilyProperties().",
             (uint64_t)physicalDevice);
     }
 }
 
+template<typename TCreateInfo, typename FPtr>
+static VkResult CreateSurface(VkInstance instance, TCreateInfo const *pCreateInfo,
+                              VkAllocationCallbacks const *pAllocator, VkSurfaceKHR *pSurface,
+                              FPtr fptr)
+{
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+
+    // Call down the call chain:
+    VkResult result = (instance_data->dispatch_table.*fptr)(instance, pCreateInfo, pAllocator, pSurface);
+
+    if (result == VK_SUCCESS) {
+        std::unique_lock<std::mutex> lock(global_lock);
+        instance_data->surface_map[*pSurface] = SURFACE_STATE(*pSurface);
+        lock.unlock();
+    }
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks *pAllocator) {
+    bool skip_call = false;
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    std::unique_lock<std::mutex> lock(global_lock);
+    auto surface_state = getSurfaceState(instance_data, surface);
+
+    if (surface_state) {
+        // TODO: track swapchains created from this surface.
+        instance_data->surface_map.erase(surface);
+    }
+    lock.unlock();
+
+    if (!skip_call) {
+        // Call down the call chain:
+        instance_data->dispatch_table.DestroySurfaceKHR(instance, surface, pAllocator);
+    }
+}
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateAndroidSurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+
+#ifdef VK_USE_PLATFORM_MIR_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateMirSurfaceKHR(VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateMirSurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_MIR_KHR
+
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+                                                       const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWaylandSurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
+                                                     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateWin32SurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+#ifdef VK_USE_PLATFORM_XCB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXcbSurfaceKHR(VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXcbSurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_XCB_KHR
+
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+VKAPI_ATTR VkResult VKAPI_CALL CreateXlibSurfaceKHR(VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
+                                                   const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    return CreateSurface(instance, pCreateInfo, pAllocator, pSurface, &VkLayerInstanceDispatchTable::CreateXlibSurfaceKHR);
+}
+#endif // VK_USE_PLATFORM_XLIB_KHR
+
+
 VKAPI_ATTR VkResult VKAPI_CALL
 CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
                              const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    VkResult res = pTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    VkResult res = instance_data->dispatch_table.CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
     if (VK_SUCCESS == res) {
         std::lock_guard<std::mutex> lock(global_lock);
-        res = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+        res = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
     }
     return res;
 }
@@ -11328,19 +11799,17 @@
 VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance,
                                                          VkDebugReportCallbackEXT msgCallback,
                                                          const VkAllocationCallbacks *pAllocator) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    pTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    instance_data->dispatch_table.DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
     std::lock_guard<std::mutex> lock(global_lock);
-    layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);
+    layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL
 DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,
                       size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    my_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
-                                                            pMsg);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    instance_data->dispatch_table.DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL
@@ -11369,9 +11838,8 @@
 
     assert(physicalDevice);
 
-    dispatch_key key = get_dispatch_key(physicalDevice);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    return my_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(physicalDevice), instance_layer_data_map);
+    return instance_data->dispatch_table.EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
 }
 
 static PFN_vkVoidFunction
@@ -11383,6 +11851,9 @@
 static PFN_vkVoidFunction
 intercept_khr_swapchain_command(const char *name, VkDevice dev);
 
+static PFN_vkVoidFunction
+intercept_khr_surface_command(const char *name, VkInstance instance);
+
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice dev, const char *funcName) {
     PFN_vkVoidFunction proc = intercept_core_device_command(funcName);
     if (proc)
@@ -11394,15 +11865,12 @@
     if (proc)
         return proc;
 
-    layer_data *dev_data;
-    dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);
 
-    VkLayerDispatchTable *pTable = dev_data->device_dispatch_table;
-    {
-        if (pTable->GetDeviceProcAddr == NULL)
-            return NULL;
-        return pTable->GetDeviceProcAddr(dev, funcName);
-    }
+    auto &table = dev_data->dispatch_table;
+    if (!table.GetDeviceProcAddr)
+        return nullptr;
+    return table.GetDeviceProcAddr(dev, funcName);
 }
 
 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
@@ -11411,21 +11879,22 @@
         proc = intercept_core_device_command(funcName);
     if (!proc)
         proc = intercept_khr_swapchain_command(funcName, VK_NULL_HANDLE);
+    if (!proc)
+        proc = intercept_khr_surface_command(funcName, instance);
     if (proc)
         return proc;
 
     assert(instance);
 
-    layer_data *my_data;
-    my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-    proc = debug_report_get_instance_proc_addr(my_data->report_data, funcName);
+    instance_layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    proc = debug_report_get_instance_proc_addr(instance_data->report_data, funcName);
     if (proc)
         return proc;
 
-    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;
-    if (pTable->GetInstanceProcAddr == NULL)
-        return NULL;
-    return pTable->GetInstanceProcAddr(instance, funcName);
+    auto &table = instance_data->dispatch_table;
+    if (!table.GetInstanceProcAddr)
+        return nullptr;
+    return table.GetInstanceProcAddr(instance, funcName);
 }
 
 static PFN_vkVoidFunction
@@ -11623,6 +12092,57 @@
     return nullptr;
 }
 
+static PFN_vkVoidFunction
+intercept_khr_surface_command(const char *name, VkInstance instance) {
+    static const struct {
+        const char *name;
+        PFN_vkVoidFunction proc;
+        bool instance_layer_data::*enable;
+    } khr_surface_commands[] = {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        {"vkCreateAndroidSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateAndroidSurfaceKHR),
+            &instance_layer_data::androidSurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        {"vkCreateMirSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateMirSurfaceKHR),
+            &instance_layer_data::mirSurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        {"vkCreateWaylandSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWaylandSurfaceKHR),
+            &instance_layer_data::waylandSurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        {"vkCreateWin32SurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateWin32SurfaceKHR),
+            &instance_layer_data::win32SurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        {"vkCreateXcbSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXcbSurfaceKHR),
+            &instance_layer_data::xcbSurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        {"vkCreateXlibSurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(CreateXlibSurfaceKHR),
+            &instance_layer_data::xlibSurfaceExtensionEnabled},
+#endif // VK_USE_PLATFORM_XLIB_KHR
+        {"vkDestroySurfaceKHR", reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR),
+            &instance_layer_data::surfaceExtensionEnabled},
+    };
+
+    instance_layer_data *instance_data = nullptr;
+    if (instance) {
+        instance_data = get_my_data_ptr(get_dispatch_key(instance), instance_layer_data_map);
+    }
+
+    for (size_t i = 0; i < ARRAY_SIZE(khr_surface_commands); i++) {
+        if (!strcmp(khr_surface_commands[i].name, name)) {
+            if (instance_data && !(instance_data->*(khr_surface_commands[i].enable)))
+                return nullptr;
+            return khr_surface_commands[i].proc;
+        }
+    }
+
+    return nullptr;
+}
+
 } // namespace core_validation
 
 // vk_layer_logging.h expects these to be defined
diff --git a/layers/core_validation.h b/layers/core_validation.h
index d7374f6..9d9769c 100644
--- a/layers/core_validation.h
+++ b/layers/core_validation.h
@@ -21,6 +21,7 @@
  * Author: Mark Lobodzinski <mark@lunarg.com>
  */
 
+#ifndef NOEXCEPT
 // Check for noexcept support
 #if defined(__clang__)
 #if __has_feature(cxx_noexcept)
@@ -41,12 +42,11 @@
 #else
 #define NOEXCEPT
 #endif
-
-// Enable mem_tracker merged code
-#define MTMERGE 1
+#endif
 
 #pragma once
 #include "core_validation_error_enums.h"
+#include "vk_validation_error_messages.h"
 #include "core_validation_types.h"
 #include "descriptor_sets.h"
 #include "vk_layer_logging.h"
@@ -60,7 +60,33 @@
 #include <list>
 #include <deque>
 
-#if MTMERGE
+/*
+ * CHECK_DISABLED struct is a container for bools that can block validation checks from being performed.
+ * The end goal is to have all checks guarded by a bool. The bools are all "false" by default meaning that all checks
+ * are enabled. At CreateInstance time, the user can use the VK_EXT_validation_flags extension to pass in enum values
+ * of VkValidationCheckEXT that will selectively disable checks.
+ */
+struct CHECK_DISABLED {
+    bool command_buffer_state;
+    bool create_descriptor_set_layout;
+    bool destroy_buffer_view; // Skip validation at DestroyBufferView time
+    bool destroy_image_view;  // Skip validation at DestroyImageView time
+    bool destroy_pipeline;    // Skip validation at DestroyPipeline time
+    bool destroy_descriptor_pool; // Skip validation at DestroyDescriptorPool time
+    bool destroy_framebuffer;     // Skip validation at DestroyFramebuffer time
+    bool destroy_renderpass;      // Skip validation at DestroyRenderpass time
+    bool destroy_image;           // Skip validation at DestroyImage time
+    bool destroy_sampler;         // Skip validation at DestroySampler time
+    bool destroy_command_pool;    // Skip validation at DestroyCommandPool time
+    bool destroy_event;           // Skip validation at DestroyEvent time
+    bool free_memory;             // Skip validation at FreeMemory time
+    bool object_in_use;       // Skip all object in_use checking
+    bool idle_descriptor_set; // Skip check to verify that descriptor set is no in-use
+    bool push_constant_range; // Skip push constant range checks
+    bool free_descriptor_sets; // Skip validation prior to vkFreeDescriptorSets()
+    bool allocate_descriptor_sets; // Skip validation prior to vkAllocateDescriptorSets()
+    bool update_descriptor_sets;   // Skip validation prior to vkUpdateDescriptorSets()
+};
 
 /*
  * MTMTODO : Update this comment
@@ -94,27 +120,11 @@
 // TODO : Could potentially store a list of freed mem allocs to flag when they're incorrectly used
 
 struct MT_FB_ATTACHMENT_INFO {
+    IMAGE_VIEW_STATE *view_state;
     VkImage image;
     VkDeviceMemory mem;
 };
 
-struct MT_DESCRIPTOR_SET_INFO {
-    std::vector<VkImageView> images;
-    std::vector<VkBuffer> buffers;
-};
-
-// Track Swapchain Information
-struct MT_SWAP_CHAIN_INFO {
-    VkSwapchainCreateInfoKHR createInfo;
-    std::vector<VkImage> images;
-};
-#endif
-
-struct SHADER_DS_MAPPING {
-    uint32_t slotCount;
-    VkDescriptorSetLayoutCreateInfo *pShaderMappingSlot;
-};
-
 struct GENERIC_HEADER {
     VkStructureType sType;
     const void *pNext;
@@ -128,7 +138,6 @@
 class PHYS_DEV_PROPERTIES_NODE {
   public:
     VkPhysicalDeviceProperties properties;
-    VkPhysicalDeviceFeatures features;
     std::vector<VkQueueFamilyProperties> queue_family_properties;
 };
 
@@ -147,14 +156,12 @@
 
 class SEMAPHORE_NODE : public BASE_NODE {
   public:
-    using BASE_NODE::in_use;
     std::pair<VkQueue, uint64_t> signaler;
     bool signaled;
 };
 
-class EVENT_NODE : public BASE_NODE {
+class EVENT_STATE : public BASE_NODE {
   public:
-    using BASE_NODE::in_use;
     int write_in_use;
     bool needsSignaled;
     VkPipelineStageFlags stageMask;
@@ -176,27 +183,19 @@
     VkQueryPoolCreateInfo createInfo;
 };
 
-class FRAMEBUFFER_NODE : BASE_NODE {
+class FRAMEBUFFER_STATE : public BASE_NODE {
   public:
-    using BASE_NODE::in_use;
-    using BASE_NODE::cb_bindings;
     VkFramebuffer framebuffer;
     safe_VkFramebufferCreateInfo createInfo;
     safe_VkRenderPassCreateInfo renderPassCreateInfo;
     std::unordered_set<VkCommandBuffer> referencingCmdBuffers;
     std::vector<MT_FB_ATTACHMENT_INFO> attachments;
-    FRAMEBUFFER_NODE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo, const VkRenderPassCreateInfo *pRPCI)
+    FRAMEBUFFER_STATE(VkFramebuffer fb, const VkFramebufferCreateInfo *pCreateInfo, const VkRenderPassCreateInfo *pRPCI)
         : framebuffer(fb), createInfo(pCreateInfo), renderPassCreateInfo(pRPCI){};
 };
 
-typedef struct stencil_data {
-    uint32_t compareMask;
-    uint32_t writeMask;
-    uint32_t reference;
-} CBStencilData;
-
 // Track command pools and their command buffers
-struct COMMAND_POOL_NODE {
+struct COMMAND_POOL_NODE : public BASE_NODE {
     VkCommandPoolCreateFlags createFlags;
     uint32_t queueFamilyIndex;
     // TODO: why is this std::list?
@@ -210,23 +209,24 @@
     QUERY_DETAILS, // Function called w/ a count to query details
 };
 
-struct INSTANCE_STATE {
-    // Track the call state and array size for physical devices
-    CALL_STATE vkEnumeratePhysicalDevicesState;
-    uint32_t physical_devices_count;
-    INSTANCE_STATE() : vkEnumeratePhysicalDevicesState(UNCALLED), physical_devices_count(0) {};
-};
-
 struct PHYSICAL_DEVICE_STATE {
     // Track the call state and array sizes for various query functions
-    CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState;
-    uint32_t queueFamilyPropertiesCount;
-    CALL_STATE vkGetPhysicalDeviceLayerPropertiesState;
-    CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState;
-    CALL_STATE vkGetPhysicalDeviceFeaturesState;
-    PHYSICAL_DEVICE_STATE()
-        : vkGetPhysicalDeviceQueueFamilyPropertiesState(UNCALLED),
-        vkGetPhysicalDeviceLayerPropertiesState(UNCALLED),
-        vkGetPhysicalDeviceExtensionPropertiesState(UNCALLED),
-        vkGetPhysicalDeviceFeaturesState(UNCALLED) {};
+    CALL_STATE vkGetPhysicalDeviceQueueFamilyPropertiesState = UNCALLED;
+    uint32_t queueFamilyPropertiesCount = 0;
+    CALL_STATE vkGetPhysicalDeviceLayerPropertiesState = UNCALLED;
+    CALL_STATE vkGetPhysicalDeviceExtensionPropertiesState = UNCALLED;
+    CALL_STATE vkGetPhysicalDeviceFeaturesState = UNCALLED;
+    VkPhysicalDeviceFeatures features = {};
+    VkPhysicalDevice phys_device = VK_NULL_HANDLE;
+    std::vector<VkQueueFamilyProperties> queue_family_properties;
+};
+
+struct SURFACE_STATE {
+    VkSurfaceKHR surface = VK_NULL_HANDLE;
+    SWAPCHAIN_NODE *swapchain = nullptr;
+    SWAPCHAIN_NODE *old_swapchain = nullptr;
+
+    SURFACE_STATE() {}
+    SURFACE_STATE(VkSurfaceKHR surface)
+        : surface(surface) {}
 };
diff --git a/layers/core_validation_error_enums.h b/layers/core_validation_error_enums.h
index e55ef3a..9f2da57 100644
--- a/layers/core_validation_error_enums.h
+++ b/layers/core_validation_error_enums.h
@@ -62,11 +62,17 @@
     DRAWSTATE_INVALID_BARRIER,               // Invalid Barrier
     DRAWSTATE_INVALID_BUFFER,                // Invalid Buffer
     DRAWSTATE_INVALID_IMAGE,                 // Invalid Image
+    DRAWSTATE_INVALID_BUFFER_VIEW,           // Invalid BufferView
+    DRAWSTATE_INVALID_IMAGE_VIEW,            // Invalid ImageView
     DRAWSTATE_INVALID_QUERY,                 // Invalid Query
     DRAWSTATE_INVALID_QUERY_POOL,            // Invalid QueryPool
+    DRAWSTATE_INVALID_DESCRIPTOR_POOL,       // Invalid DescriptorPool
+    DRAWSTATE_INVALID_COMMAND_POOL,          // Invalid CommandPool
     DRAWSTATE_INVALID_FENCE,                 // Invalid Fence
     DRAWSTATE_INVALID_EVENT,                 // Invalid Event
     DRAWSTATE_INVALID_SAMPLER,               // Invalid Sampler
+    DRAWSTATE_INVALID_FRAMEBUFFER,           // Invalid Framebuffer
+    DRAWSTATE_INVALID_DEVICE_MEMORY,         // Invalid DeviceMemory
     DRAWSTATE_VTX_INDEX_OUT_OF_BOUNDS,       // binding in vkCmdBindVertexData() too
                                              // large for PSO's
                                              // pVertexBindingDescriptions array
@@ -219,8 +225,6 @@
                                              // elements of pAttachmentsMustBeIdentical
     DRAWSTATE_DISABLED_LOGIC_OP,             // If logic operations is not enabled, logicOpEnable
                                              // must be VK_FALSE
-    DRAWSTATE_INVALID_LOGIC_OP,              // If logicOpEnable is VK_TRUE, logicOp must
-                                             // must be a valid VkLogicOp value
     DRAWSTATE_INVALID_QUEUE_INDEX,           // Specified queue index exceeds number
                                              // of queried queue families
     DRAWSTATE_INVALID_QUEUE_FAMILY,          // Command buffer submitted on queue is from
@@ -229,6 +233,11 @@
                                              // granularity
     DRAWSTATE_PUSH_CONSTANTS_ERROR,          // Push constants exceed maxPushConstantSize
     DRAWSTATE_INVALID_SUBPASS_INDEX,         // Stepping beyond last subpass, or not reaching it
+    DRAWSTATE_SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, // AcquireNextImageKHR with no sync object
+    DRAWSTATE_SWAPCHAIN_INVALID_IMAGE,       // QueuePresentKHR with image index out of range
+    DRAWSTATE_SWAPCHAIN_IMAGE_NOT_ACQUIRED,  // QueuePresentKHR with image not acquired by app
+    DRAWSTATE_SWAPCHAIN_ALREADY_EXISTS,      // Surface has an existing swapchain that is not being replaced
+    DRAWSTATE_SWAPCHAIN_WRONG_SURFACE,       // Swapchain being replaced is not attached to the same surface
 };
 
 // Shader Checker ERROR codes
diff --git a/layers/core_validation_types.h b/layers/core_validation_types.h
index 4edfa9c..8e6c563 100644
--- a/layers/core_validation_types.h
+++ b/layers/core_validation_types.h
@@ -23,6 +23,7 @@
 #ifndef CORE_VALIDATION_TYPES_H_
 #define CORE_VALIDATION_TYPES_H_
 
+#ifndef NOEXCEPT
 // Check for noexcept support
 #if defined(__clang__)
 #if __has_feature(cxx_noexcept)
@@ -43,6 +44,7 @@
 #else
 #define NOEXCEPT
 #endif
+#endif
 
 #include "vk_safe_struct.h"
 #include "vulkan/vulkan.h"
@@ -108,7 +110,7 @@
     DESCRIPTOR_REQ_MULTI_SAMPLE = DESCRIPTOR_REQ_SINGLE_SAMPLE << 1,
 };
 
-struct DESCRIPTOR_POOL_NODE {
+struct DESCRIPTOR_POOL_STATE : BASE_NODE {
     VkDescriptorPool pool;
     uint32_t maxSets;       // Max descriptor sets allowed in this pool
     uint32_t availableSets; // Available descriptor sets in this pool
@@ -118,7 +120,7 @@
     std::vector<uint32_t> maxDescriptorTypeCount;              // Max # of descriptors of each type in this pool
     std::vector<uint32_t> availableDescriptorTypeCount;        // Available # of descriptors of each type in this pool
 
-    DESCRIPTOR_POOL_NODE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
+    DESCRIPTOR_POOL_STATE(const VkDescriptorPool pool, const VkDescriptorPoolCreateInfo *pCreateInfo)
         : pool(pool), maxSets(pCreateInfo->maxSets), availableSets(pCreateInfo->maxSets), createInfo(*pCreateInfo),
           maxDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0), availableDescriptorTypeCount(VK_DESCRIPTOR_TYPE_RANGE_SIZE, 0) {
         if (createInfo.poolSizeCount) { // Shadow type struct from ptr into local struct
@@ -137,70 +139,96 @@
             createInfo.pPoolSizes = NULL; // Make sure this is NULL so we don't try to clean it up
         }
     }
-    ~DESCRIPTOR_POOL_NODE() {
+    ~DESCRIPTOR_POOL_STATE() {
         delete[] createInfo.pPoolSizes;
         // TODO : pSets are currently freed in deletePools function which uses freeShadowUpdateTree function
         //  need to migrate that struct to smart ptrs for auto-cleanup
     }
 };
 
-class BUFFER_NODE : public BASE_NODE {
-  public:
-    using BASE_NODE::in_use;
-    VkBuffer buffer;
+// Generic memory binding struct to track objects bound to objects
+struct MEM_BINDING {
     VkDeviceMemory mem;
-    VkDeviceSize memOffset;
-    VkDeviceSize memSize; // Note: may differ from createInfo::size
-    VkBufferCreateInfo createInfo;
-    BUFFER_NODE() : buffer(VK_NULL_HANDLE), mem(VK_NULL_HANDLE), memOffset(0), memSize(0), createInfo{} { in_use.store(0); };
-    BUFFER_NODE(VkBuffer buff, const VkBufferCreateInfo *pCreateInfo)
-        : buffer(buff), mem(VK_NULL_HANDLE), memOffset(0), memSize(0), createInfo(*pCreateInfo){};
-    BUFFER_NODE(const BUFFER_NODE &rh_obj)
-        : buffer(rh_obj.buffer), mem(rh_obj.mem), memOffset(rh_obj.memOffset), memSize(rh_obj.memSize),
-          createInfo(rh_obj.createInfo){};
+    VkDeviceSize offset;
+    VkDeviceSize size;
 };
 
-struct SAMPLER_NODE : public BASE_NODE {
+inline bool operator==(MEM_BINDING a, MEM_BINDING b) NOEXCEPT { return a.mem == b.mem && a.offset == b.offset && a.size == b.size; }
+
+namespace std {
+template <> struct hash<MEM_BINDING> {
+    size_t operator()(MEM_BINDING mb) const NOEXCEPT {
+        auto intermediate = hash<uint64_t>()(reinterpret_cast<uint64_t &>(mb.mem)) ^ hash<uint64_t>()(mb.offset);
+        return intermediate ^ hash<uint64_t>()(mb.size);
+    }
+};
+}
+
+// Superclass for bindable object state (currently imagesa and buffers)
+class BINDABLE : public BASE_NODE {
+  public:
+    bool sparse; // Is this object being bound with sparse memory or not?
+    // Non-sparse binding data
+    MEM_BINDING binding;
+    // Sparse binding data, initially just tracking MEM_BINDING per mem object
+    //  There's more data for sparse bindings so need better long-term solution
+    // TODO : Need to update solution to track all sparse binding data
+    std::unordered_set<MEM_BINDING> sparse_bindings;
+    BINDABLE() : sparse(false), binding{}, sparse_bindings{}{};
+};
+
+class BUFFER_NODE : public BINDABLE {
+  public:
+    VkBuffer buffer;
+    VkBufferCreateInfo createInfo;
+    BUFFER_NODE(VkBuffer buff, const VkBufferCreateInfo *pCreateInfo) : buffer(buff), createInfo(*pCreateInfo) {
+        if (createInfo.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
+            sparse = true;
+        }
+    };
+
+    BUFFER_NODE(BUFFER_NODE const &rh_obj) = delete;
+};
+
+class BUFFER_VIEW_STATE : public BASE_NODE {
+  public:
+    VkBufferView buffer_view;
+    VkBufferViewCreateInfo create_info;
+    BUFFER_VIEW_STATE(VkBufferView bv, const VkBufferViewCreateInfo *ci) : buffer_view(bv), create_info(*ci){};
+    BUFFER_VIEW_STATE(const BUFFER_VIEW_STATE &rh_obj) = delete;
+};
+
+struct SAMPLER_STATE : public BASE_NODE {
     VkSampler sampler;
     VkSamplerCreateInfo createInfo;
 
-    SAMPLER_NODE(const VkSampler *ps, const VkSamplerCreateInfo *pci) : sampler(*ps), createInfo(*pci){};
+    SAMPLER_STATE(const VkSampler *ps, const VkSamplerCreateInfo *pci) : sampler(*ps), createInfo(*pci){};
 };
 
-class IMAGE_NODE : public BASE_NODE {
+class IMAGE_STATE : public BINDABLE {
   public:
-    using BASE_NODE::in_use;
     VkImage image;
     VkImageCreateInfo createInfo;
-    VkDeviceMemory mem;
     bool valid; // If this is a swapchain image backing memory track valid here as it doesn't have DEVICE_MEM_INFO
-    VkDeviceSize memOffset;
-    VkDeviceSize memSize;
-    IMAGE_NODE() : image(VK_NULL_HANDLE), createInfo{}, mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0){};
-    IMAGE_NODE(VkImage img, const VkImageCreateInfo *pCreateInfo)
-        : image(img), createInfo(*pCreateInfo), mem(VK_NULL_HANDLE), valid(false), memOffset(0), memSize(0){};
-    IMAGE_NODE(const IMAGE_NODE &rh_obj)
-        : image(rh_obj.image), createInfo(rh_obj.createInfo), mem(rh_obj.mem), valid(rh_obj.valid), memOffset(rh_obj.memOffset),
-          memSize(rh_obj.memSize) {
-        in_use.store(rh_obj.in_use.load());
+    bool acquired;  // If this is a swapchain image, has it been acquired by the app.
+    IMAGE_STATE(VkImage img, const VkImageCreateInfo *pCreateInfo)
+        : image(img), createInfo(*pCreateInfo), valid(false), acquired(false) {
+        if (createInfo.flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
+            sparse = true;
+        }
     };
+
+    IMAGE_STATE(IMAGE_STATE const &rh_obj) = delete;
 };
 
-// Simple struct to hold handle and type of object so they can be uniquely identified and looked up in appropriate map
-// TODO : Unify this with VK_OBJECT above
-struct MT_OBJ_HANDLE_TYPE {
-    uint64_t handle;
-    VkDebugReportObjectTypeEXT type;
+class IMAGE_VIEW_STATE : public BASE_NODE {
+  public:
+    VkImageView image_view;
+    VkImageViewCreateInfo create_info;
+    IMAGE_VIEW_STATE(VkImageView iv, const VkImageViewCreateInfo *ci) : image_view(iv), create_info(*ci){};
+    IMAGE_VIEW_STATE(const IMAGE_VIEW_STATE &rh_obj) = delete;
 };
 
-inline bool operator==(MT_OBJ_HANDLE_TYPE a, MT_OBJ_HANDLE_TYPE b) NOEXCEPT { return a.handle == b.handle && a.type == b.type; }
-
-namespace std {
-template <> struct hash<MT_OBJ_HANDLE_TYPE> {
-    size_t operator()(MT_OBJ_HANDLE_TYPE obj) const NOEXCEPT { return hash<uint64_t>()(obj.handle) ^ hash<uint32_t>()(obj.type); }
-};
-}
-
 struct MemRange {
     VkDeviceSize offset;
     VkDeviceSize size;
@@ -220,13 +248,12 @@
 };
 
 // Data struct for tracking memory object
-struct DEVICE_MEM_INFO {
+struct DEVICE_MEM_INFO : public BASE_NODE {
     void *object; // Dispatchable object used to create this memory (device of swapchain)
     bool global_valid; // If allocation is mapped, set to "true" to be picked up by subsequently bound ranges
     VkDeviceMemory mem;
     VkMemoryAllocateInfo alloc_info;
-    std::unordered_set<MT_OBJ_HANDLE_TYPE> obj_bindings;         // objects bound to this memory
-    std::unordered_set<VkCommandBuffer> command_buffer_bindings; // cmd buffers referencing this memory
+    std::unordered_set<VK_OBJECT> obj_bindings;         // objects bound to this memory
     std::unordered_map<uint64_t, MEMORY_RANGE> bound_ranges;     // Map of object to its binding range
     // Convenience vectors image/buff handles to speed up iterating over images or buffers independently
     std::unordered_set<uint64_t> bound_images;
@@ -246,17 +273,11 @@
 
 class SWAPCHAIN_NODE {
   public:
-    VkSwapchainCreateInfoKHR createInfo;
-    uint32_t *pQueueFamilyIndices;
+    safe_VkSwapchainCreateInfoKHR createInfo;
+    VkSwapchainKHR swapchain;
     std::vector<VkImage> images;
-    SWAPCHAIN_NODE(const VkSwapchainCreateInfoKHR *pCreateInfo) : createInfo(*pCreateInfo), pQueueFamilyIndices(NULL) {
-        if (pCreateInfo->queueFamilyIndexCount && pCreateInfo->imageSharingMode == VK_SHARING_MODE_CONCURRENT) {
-            pQueueFamilyIndices = new uint32_t[pCreateInfo->queueFamilyIndexCount];
-            memcpy(pQueueFamilyIndices, pCreateInfo->pQueueFamilyIndices, pCreateInfo->queueFamilyIndexCount * sizeof(uint32_t));
-            createInfo.pQueueFamilyIndices = pQueueFamilyIndices;
-        }
-    }
-    ~SWAPCHAIN_NODE() { delete[] pQueueFamilyIndices; }
+    SWAPCHAIN_NODE(const VkSwapchainCreateInfoKHR *pCreateInfo, VkSwapchainKHR swapchain)
+        : createInfo(pCreateInfo), swapchain(swapchain) {}
 };
 
 enum DRAW_TYPE {
@@ -271,7 +292,7 @@
 
 class IMAGE_CMD_BUF_LAYOUT_NODE {
   public:
-    IMAGE_CMD_BUF_LAYOUT_NODE() {}
+    IMAGE_CMD_BUF_LAYOUT_NODE() = default;
     IMAGE_CMD_BUF_LAYOUT_NODE(VkImageLayout initialLayoutInput, VkImageLayout layoutInput)
         : initialLayout(initialLayoutInput), layout(layoutInput) {}
 
@@ -279,14 +300,6 @@
     VkImageLayout layout;
 };
 
-struct MT_PASS_ATTACHMENT_INFO {
-    uint32_t attachment;
-    VkAttachmentLoadOp load_op;
-    VkAttachmentStoreOp store_op;
-    VkAttachmentLoadOp stencil_load_op;
-    VkAttachmentStoreOp stencil_store_op;
-};
-
 // Store the DAG.
 struct DAGNode {
     uint32_t pass;
@@ -294,40 +307,15 @@
     std::vector<uint32_t> next;
 };
 
-struct RENDER_PASS_NODE {
+struct RENDER_PASS_STATE : public BASE_NODE {
     VkRenderPass renderPass;
-    VkRenderPassCreateInfo const *pCreateInfo;
+    safe_VkRenderPassCreateInfo createInfo;
     std::vector<bool> hasSelfDependency;
     std::vector<DAGNode> subpassToNode;
-    std::vector<std::vector<VkFormat>> subpassColorFormats;
-    std::vector<MT_PASS_ATTACHMENT_INFO> attachments;
     std::unordered_map<uint32_t, bool> attachment_first_read;
     std::unordered_map<uint32_t, VkImageLayout> attachment_first_layout;
 
-    RENDER_PASS_NODE(VkRenderPassCreateInfo const *pCreateInfo) : pCreateInfo(pCreateInfo) {
-        uint32_t i;
-
-        subpassColorFormats.reserve(pCreateInfo->subpassCount);
-        for (i = 0; i < pCreateInfo->subpassCount; i++) {
-            const VkSubpassDescription *subpass = &pCreateInfo->pSubpasses[i];
-            std::vector<VkFormat> color_formats;
-            uint32_t j;
-
-            color_formats.reserve(subpass->colorAttachmentCount);
-            for (j = 0; j < subpass->colorAttachmentCount; j++) {
-                const uint32_t att = subpass->pColorAttachments[j].attachment;
-
-                if (att != VK_ATTACHMENT_UNUSED) {
-                    color_formats.push_back(pCreateInfo->pAttachments[att].format);
-                }
-                else {
-                    color_formats.push_back(VK_FORMAT_UNDEFINED);
-                }
-            }
-
-            subpassColorFormats.push_back(color_formats);
-        }
-    }
+    RENDER_PASS_STATE(VkRenderPassCreateInfo const *pCreateInfo) : createInfo(pCreateInfo) {}
 };
 
 // Cmd Buffer Tracking
@@ -402,17 +390,15 @@
 enum CBStatusFlagBits {
     // clang-format off
     CBSTATUS_NONE                   = 0x00000000,   // No status is set
-    CBSTATUS_VIEWPORT_SET           = 0x00000001,   // Viewport has been set
-    CBSTATUS_LINE_WIDTH_SET         = 0x00000002,   // Line width has been set
-    CBSTATUS_DEPTH_BIAS_SET         = 0x00000004,   // Depth bias has been set
-    CBSTATUS_BLEND_CONSTANTS_SET    = 0x00000008,   // Blend constants state has been set
-    CBSTATUS_DEPTH_BOUNDS_SET       = 0x00000010,   // Depth bounds state object has been set
-    CBSTATUS_STENCIL_READ_MASK_SET  = 0x00000020,   // Stencil read mask has been set
-    CBSTATUS_STENCIL_WRITE_MASK_SET = 0x00000040,   // Stencil write mask has been set
-    CBSTATUS_STENCIL_REFERENCE_SET  = 0x00000080,   // Stencil reference has been set
-    CBSTATUS_SCISSOR_SET            = 0x00000100,   // Scissor has been set
-    CBSTATUS_INDEX_BUFFER_BOUND     = 0x00000200,   // Index buffer has been set
-    CBSTATUS_ALL                    = 0x000001FF,   // All dynamic state set (intentionally exclude index buffer)
+    CBSTATUS_LINE_WIDTH_SET         = 0x00000001,   // Line width has been set
+    CBSTATUS_DEPTH_BIAS_SET         = 0x00000002,   // Depth bias has been set
+    CBSTATUS_BLEND_CONSTANTS_SET    = 0x00000004,   // Blend constants state has been set
+    CBSTATUS_DEPTH_BOUNDS_SET       = 0x00000008,   // Depth bounds state object has been set
+    CBSTATUS_STENCIL_READ_MASK_SET  = 0x00000010,   // Stencil read mask has been set
+    CBSTATUS_STENCIL_WRITE_MASK_SET = 0x00000020,   // Stencil write mask has been set
+    CBSTATUS_STENCIL_REFERENCE_SET  = 0x00000040,   // Stencil reference has been set
+    CBSTATUS_INDEX_BUFFER_BOUND     = 0x00000080,   // Index buffer has been set
+    CBSTATUS_ALL_STATE_SET          = 0x0000007F,   // All state set (intentionally exclude index buffer)
     // clang-format on
 };
 
@@ -478,7 +464,7 @@
     }
 };
 
-class PIPELINE_NODE : public BASE_NODE {
+class PIPELINE_STATE : public BASE_NODE {
   public:
     VkPipeline pipeline;
     safe_VkGraphicsPipelineCreateInfo graphicsPipelineCI;
@@ -498,7 +484,7 @@
     PIPELINE_LAYOUT_NODE pipeline_layout;
 
     // Default constructor
-    PIPELINE_NODE()
+    PIPELINE_STATE()
         : pipeline{}, graphicsPipelineCI{}, computePipelineCI{}, active_shaders(0), duplicate_shaders(0), active_slots(),
           vertexBindingDescriptions(), vertexAttributeDescriptions(), attachments(), blendConstantsEnabled(false), render_pass_ci(),
           pipeline_layout() {}
@@ -551,7 +537,7 @@
 
 // Track last states that are bound per pipeline bind point (Gfx & Compute)
 struct LAST_BOUND_STATE {
-    PIPELINE_NODE *pipeline_node;
+    PIPELINE_STATE *pipeline_state;
     PIPELINE_LAYOUT_NODE pipeline_layout;
     // Track each set that has been bound
     // Ordered bound set tracking where index is set# that given set is bound to
@@ -560,7 +546,7 @@
     std::vector<std::vector<uint32_t>> dynamicOffsets;
 
     void reset() {
-        pipeline_node = nullptr;
+        pipeline_state = nullptr;
         pipeline_layout.reset();
         boundDescriptorSets.clear();
         dynamicOffsets.clear();
@@ -588,7 +574,7 @@
     uint32_t viewportMask;
     uint32_t scissorMask;
     VkRenderPassBeginInfo activeRenderPassBeginInfo;
-    RENDER_PASS_NODE *activeRenderPass;
+    RENDER_PASS_STATE *activeRenderPass;
     VkSubpassContents activeSubpassContents;
     uint32_t activeSubpass;
     VkFramebuffer activeFramebuffer;
@@ -645,20 +631,23 @@
 struct layer_data;
 cvdescriptorset::DescriptorSet *getSetNode(const layer_data *, VkDescriptorSet);
 cvdescriptorset::DescriptorSetLayout const *getDescriptorSetLayout(layer_data const *, VkDescriptorSetLayout);
-DESCRIPTOR_POOL_NODE *getPoolNode(const layer_data *, const VkDescriptorPool);
+DESCRIPTOR_POOL_STATE *getDescriptorPoolState(const layer_data *, const VkDescriptorPool);
 BUFFER_NODE *getBufferNode(const layer_data *, VkBuffer);
-IMAGE_NODE *getImageNode(const layer_data *, VkImage);
+IMAGE_STATE *getImageState(const layer_data *, VkImage);
 DEVICE_MEM_INFO *getMemObjInfo(const layer_data *, VkDeviceMemory);
-VkBufferViewCreateInfo *getBufferViewInfo(const layer_data *, VkBufferView);
-SAMPLER_NODE *getSamplerNode(const layer_data *, VkSampler);
-VkImageViewCreateInfo *getImageViewData(const layer_data *, VkImageView);
+BUFFER_VIEW_STATE *getBufferViewState(const layer_data *, VkBufferView);
+SAMPLER_STATE *getSamplerState(const layer_data *, VkSampler);
+IMAGE_VIEW_STATE *getImageViewState(const layer_data *, VkImageView);
 VkSwapchainKHR getSwapchainFromImage(const layer_data *, VkImage);
 SWAPCHAIN_NODE *getSwapchainNode(const layer_data *, VkSwapchainKHR);
 void invalidateCommandBuffers(std::unordered_set<GLOBAL_CB_NODE *>, VK_OBJECT);
 bool ValidateMemoryIsBoundToBuffer(const layer_data *, const BUFFER_NODE *, const char *);
-void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *, SAMPLER_NODE *);
-void AddCommandBufferBindingImage(const layer_data *, GLOBAL_CB_NODE *, IMAGE_NODE *);
+bool ValidateMemoryIsBoundToImage(const layer_data *, const IMAGE_STATE *, const char *);
+void AddCommandBufferBindingSampler(GLOBAL_CB_NODE *, SAMPLER_STATE *);
+void AddCommandBufferBindingImage(const layer_data *, GLOBAL_CB_NODE *, IMAGE_STATE *);
+void AddCommandBufferBindingImageView(const layer_data *, GLOBAL_CB_NODE *, IMAGE_VIEW_STATE *);
 void AddCommandBufferBindingBuffer(const layer_data *, GLOBAL_CB_NODE *, BUFFER_NODE *);
+void AddCommandBufferBindingBufferView(const layer_data *, GLOBAL_CB_NODE *, BUFFER_VIEW_STATE *);
 }
 
 #endif // CORE_VALIDATION_TYPES_H_
diff --git a/layers/descriptor_sets.cpp b/layers/descriptor_sets.cpp
index 9b20638..6c8be9c 100644
--- a/layers/descriptor_sets.cpp
+++ b/layers/descriptor_sets.cpp
@@ -24,23 +24,17 @@
 #include <sstream>
 
 // Construct DescriptorSetLayout instance from given create info
-cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(debug_report_data *report_data,
-                                                          const VkDescriptorSetLayoutCreateInfo *p_create_info,
+cvdescriptorset::DescriptorSetLayout::DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info,
                                                           const VkDescriptorSetLayout layout)
     : layout_(layout), binding_count_(p_create_info->bindingCount), descriptor_count_(0), dynamic_descriptor_count_(0) {
     uint32_t global_index = 0;
     for (uint32_t i = 0; i < binding_count_; ++i) {
         descriptor_count_ += p_create_info->pBindings[i].descriptorCount;
-        if (!binding_to_index_map_.emplace(p_create_info->pBindings[i].binding, i).second) {
-            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT,
-                    reinterpret_cast<uint64_t &>(layout_), __LINE__, DRAWSTATE_INVALID_LAYOUT, "DS",
-                    "duplicated binding number in "
-                    "VkDescriptorSetLayoutBinding");
-        }
+        binding_to_index_map_[p_create_info->pBindings[i].binding] = i;
         binding_to_global_start_index_map_[p_create_info->pBindings[i].binding] = global_index;
         global_index += p_create_info->pBindings[i].descriptorCount ? p_create_info->pBindings[i].descriptorCount - 1 : 0;
         binding_to_global_end_index_map_[p_create_info->pBindings[i].binding] = global_index;
-        global_index++;
+        global_index += p_create_info->pBindings[i].descriptorCount ? 1 : 0;
         bindings_.push_back(safe_VkDescriptorSetLayoutBinding(&p_create_info->pBindings[i]));
         // In cases where we should ignore pImmutableSamplers make sure it's NULL
         if ((p_create_info->pBindings[i].pImmutableSamplers) &&
@@ -54,6 +48,22 @@
         }
     }
 }
+
+// Validate descriptor set layout create info
+bool cvdescriptorset::DescriptorSetLayout::ValidateCreateInfo(debug_report_data *report_data,
+                                                              const VkDescriptorSetLayoutCreateInfo *create_info) {
+    bool skip = false;
+    std::unordered_set<uint32_t> bindings;
+    for (uint32_t i = 0; i < create_info->bindingCount; ++i) {
+        if (!bindings.insert(create_info->pBindings[i].binding).second) {
+            skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                            VALIDATION_ERROR_02345, "DS", "duplicated binding number in VkDescriptorSetLayoutBinding. %s",
+                            validation_error_map[VALIDATION_ERROR_02345]);
+        }
+    }
+    return skip;
+}
+
 // put all bindings into the given set
 void cvdescriptorset::DescriptorSetLayout::FillBindingSet(std::unordered_set<uint32_t> *binding_set) const {
     for (auto binding_index_pair : binding_to_index_map_)
@@ -265,9 +275,10 @@
 cvdescriptorset::AllocateDescriptorSetsData::AllocateDescriptorSetsData(uint32_t count)
     : required_descriptors_by_type{}, layout_nodes(count, nullptr) {}
 
-cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, const DescriptorSetLayout *layout,
-                                              const core_validation::layer_data *dev_data)
-    : some_update_(false), set_(set), p_layout_(layout), device_data_(dev_data) {
+cvdescriptorset::DescriptorSet::DescriptorSet(const VkDescriptorSet set, const VkDescriptorPool pool,
+                                              const DescriptorSetLayout *layout, const core_validation::layer_data *dev_data)
+    : some_update_(false), set_(set), pool_state_(nullptr), p_layout_(layout), device_data_(dev_data) {
+    pool_state_ = getDescriptorPoolState(dev_data, pool);
     // Foreach binding, create default descriptors of given type
     for (uint32_t i = 0; i < p_layout_->GetBindingCount(); ++i) {
         auto type = p_layout_->GetTypeFromIndex(i);
@@ -385,12 +396,12 @@
                             *error = error_str.str();
                             return false;
                         } else {
-                            auto mem_entry = getMemObjInfo(device_data_, buffer_node->mem);
+                            auto mem_entry = getMemObjInfo(device_data_, buffer_node->binding.mem);
                             if (!mem_entry) {
                                 std::stringstream error_str;
                                 error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
-                                          << " uses buffer " << buffer << " that references invalid memory " << buffer_node->mem
-                                          << ".";
+                                          << " uses buffer " << buffer << " that references invalid memory "
+                                          << buffer_node->binding.mem << ".";
                                 *error = error_str.str();
                                 return false;
                             }
@@ -431,20 +442,21 @@
                                 : static_cast<ImageDescriptor *>(descriptors_[i].get())->GetImageView();
                         auto reqs = binding_pair.second;
 
-                        auto image_view_data = getImageViewData(device_data_, image_view);
-                        assert(image_view_data);
+                        auto image_view_state = getImageViewState(device_data_, image_view);
+                        assert(image_view_state);
+                        auto image_view_ci = image_view_state->create_info;
 
-                        if ((reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) && (~reqs & (1 << image_view_data->viewType))) {
+                        if ((reqs & DESCRIPTOR_REQ_ALL_VIEW_TYPE_BITS) && (~reqs & (1 << image_view_ci.viewType))) {
                             // bad view type
                             std::stringstream error_str;
                             error_str << "Descriptor in binding #" << binding << " at global descriptor index " << i
                                       << " requires an image view of type " << string_descriptor_req_view_type(reqs)
-                                      << " but got " << string_VkImageViewType(image_view_data->viewType) << ".";
+                                      << " but got " << string_VkImageViewType(image_view_ci.viewType) << ".";
                             *error = error_str.str();
                             return false;
                         }
 
-                        auto image_node = getImageNode(device_data_, image_view_data->image);
+                        auto image_node = getImageState(device_data_, image_view_ci.image);
                         assert(image_node);
 
                         if ((reqs & DESCRIPTOR_REQ_SINGLE_SAMPLE) &&
@@ -497,9 +509,9 @@
                 for (uint32_t i = 0; i < p_layout_->GetDescriptorCountFromBinding(binding); ++i) {
                     if (descriptors_[start_idx + i]->updated) {
                         auto bufferview = static_cast<TexelDescriptor *>(descriptors_[start_idx + i].get())->GetBufferView();
-                        auto bv_info = getBufferViewInfo(device_data_, bufferview);
-                        if (bv_info) {
-                            buffer_set->insert(bv_info->buffer);
+                        auto bv_state = getBufferViewState(device_data_, bufferview);
+                        if (bv_state) {
+                            buffer_set->insert(bv_state->create_info.buffer);
                             num_updates++;
                         }
                     }
@@ -535,25 +547,30 @@
 }
 // Validate Copy update
 bool cvdescriptorset::DescriptorSet::ValidateCopyUpdate(const debug_report_data *report_data, const VkCopyDescriptorSet *update,
-                                                        const DescriptorSet *src_set, std::string *error) {
+                                                        const DescriptorSet *src_set, UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                        std::string *error_msg) {
     // Verify idle ds
     if (in_use.load()) {
+        // TODO : Re-using Allocate Idle error code, need copy update idle error code
+        *error_code = VALIDATION_ERROR_00919;
         std::stringstream error_str;
         error_str << "Cannot call vkUpdateDescriptorSets() to perform copy update on descriptor set " << set_
                   << " that is in use by a command buffer.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     if (!p_layout_->HasBinding(update->dstBinding)) {
+        *error_code = VALIDATION_ERROR_00966;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have copy update dest binding of " << update->dstBinding << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     if (!src_set->HasBinding(update->srcBinding)) {
+        *error_code = VALIDATION_ERROR_00964;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have copy update src binding of " << update->srcBinding << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // src & dst set bindings are valid
@@ -561,26 +578,31 @@
     auto src_start_idx = src_set->GetGlobalStartIndexFromBinding(update->srcBinding) + update->srcArrayElement;
     if ((src_start_idx + update->descriptorCount) > src_set->GetTotalDescriptorCount()) {
         // SRC update out of bounds
+        *error_code = VALIDATION_ERROR_00965;
         std::stringstream error_str;
         error_str << "Attempting copy update from descriptorSet " << update->srcSet << " binding#" << update->srcBinding
                   << " with offset index of " << src_set->GetGlobalStartIndexFromBinding(update->srcBinding)
                   << " plus update array offset of " << update->srcArrayElement << " and update of " << update->descriptorCount
                   << " descriptors oversteps total number of descriptors in set: " << src_set->GetTotalDescriptorCount() << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     auto dst_start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
     if ((dst_start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
         // DST update out of bounds
+        *error_code = VALIDATION_ERROR_00967;
         std::stringstream error_str;
         error_str << "Attempting copy update to descriptorSet " << set_ << " binding#" << update->dstBinding
                   << " with offset index of " << p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding)
                   << " plus update array offset of " << update->dstArrayElement << " and update of " << update->descriptorCount
                   << " descriptors oversteps total number of descriptors in set: " << p_layout_->GetTotalDescriptorCount() << ".";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Check that types match
+    // TODO : Base default error case going from here is VALIDATION_ERROR_00968 which covers all consistency issues, need more
+    // fine-grained error codes
+    *error_code = VALIDATION_ERROR_00968;
     auto src_type = src_set->GetTypeFromBinding(update->srcBinding);
     auto dst_type = p_layout_->GetTypeFromBinding(update->dstBinding);
     if (src_type != dst_type) {
@@ -588,14 +610,14 @@
         error_str << "Attempting copy update to descriptorSet " << set_ << " binding #" << update->dstBinding << " with type "
                   << string_VkDescriptorType(dst_type) << " from descriptorSet " << src_set->GetSet() << " binding #"
                   << update->srcBinding << " with type " << string_VkDescriptorType(src_type) << ". Types do not match.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Verify consistency of src & dst bindings if update crosses binding boundaries
     if ((!src_set->GetLayout()->VerifyUpdateConsistency(update->srcBinding, update->srcArrayElement, update->descriptorCount,
-                                                        "copy update from", src_set->GetSet(), error)) ||
+                                                        "copy update from", src_set->GetSet(), error_msg)) ||
         (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount, "copy update to",
-                                             set_, error))) {
+                                             set_, error_msg))) {
         return false;
     }
     // First make sure source descriptors are updated
@@ -604,12 +626,12 @@
             std::stringstream error_str;
             error_str << "Attempting copy update from descriptorSet " << src_set << " binding #" << update->srcBinding << " but descriptor at array offset "
                       << update->srcArrayElement + i << " has not been updated.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
     }
     // Update parameters all look good and descriptor updated so verify update contents
-    if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, error))
+    if (!VerifyCopyUpdateContents(update, src_set, src_type, src_start_idx, error_code, error_msg))
         return false;
 
     // All checks passed so update is good
@@ -635,8 +657,11 @@
 void cvdescriptorset::DescriptorSet::BindCommandBuffer(GLOBAL_CB_NODE *cb_node, const std::unordered_set<uint32_t> &bindings) {
     // bind cb to this descriptor set
     cb_bindings.insert(cb_node);
-    // Add bindings for descriptor set and individual objects in the set
+    // Add bindings for descriptor set, the set's pool, and individual objects in the set
     cb_node->object_bindings.insert({reinterpret_cast<uint64_t &>(set_), VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT});
+    pool_state_->cb_bindings.insert(cb_node);
+    cb_node->object_bindings.insert(
+        {reinterpret_cast<uint64_t &>(pool_state_->pool), VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT});
     // For the active slots, use set# to look up descriptorSet from boundDescriptorSets, and bind all of that descriptor set's
     // resources
     for (auto binding : bindings) {
@@ -664,30 +689,38 @@
 }
 // Validate given sampler. Currently this only checks to make sure it exists in the samplerMap
 bool cvdescriptorset::ValidateSampler(const VkSampler sampler, const core_validation::layer_data *dev_data) {
-    return (getSamplerNode(dev_data, sampler) != nullptr);
+    return (getSamplerState(dev_data, sampler) != nullptr);
 }
 
 bool cvdescriptorset::ValidateImageUpdate(VkImageView image_view, VkImageLayout image_layout, VkDescriptorType type,
-                                          const core_validation::layer_data *dev_data,
-                                          std::string *error) {
-    auto iv_data = getImageViewData(dev_data, image_view);
-    if (!iv_data) {
+                                          const core_validation::layer_data *dev_data, UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                          std::string *error_msg) {
+    // TODO : Defaulting to 00943 for all cases here. Need to create new error codes for various cases.
+    *error_code = VALIDATION_ERROR_00943;
+    auto iv_state = getImageViewState(dev_data, image_view);
+    if (!iv_state) {
         std::stringstream error_str;
         error_str << "Invalid VkImageView: " << image_view;
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     // Note that when an imageview is created, we validated that memory is bound so no need to re-check here
     // Validate that imageLayout is compatible with aspect_mask and image format
     //  and validate that image usage bits are correct for given usage
-    VkImageAspectFlags aspect_mask = iv_data->subresourceRange.aspectMask;
-    VkImage image = iv_data->image;
+    VkImageAspectFlags aspect_mask = iv_state->create_info.subresourceRange.aspectMask;
+    VkImage image = iv_state->create_info.image;
     VkFormat format = VK_FORMAT_MAX_ENUM;
     VkImageUsageFlags usage = 0;
-    auto image_node = getImageNode(dev_data, image);
+    auto image_node = getImageState(dev_data, image);
     if (image_node) {
         format = image_node->createInfo.format;
         usage = image_node->createInfo.usage;
+        // Validate that memory is bound to image
+        if (ValidateMemoryIsBoundToImage(dev_data, image_node, "vkUpdateDescriptorSets()")) {
+            // TODO : Need new code(s) for language in 11.6 Memory Association
+            *error_msg = "No memory bound to image.";
+            return false;
+        }
     } else {
         // Also need to check the swapchains.
         auto swapchain = getSwapchainFromImage(dev_data, image);
@@ -702,9 +735,11 @@
     if (format == VK_FORMAT_MAX_ENUM) {
         std::stringstream error_str;
         error_str << "Invalid image (" << image << ") in imageView (" << image_view << ").";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
+    // TODO : The various image aspect and format checks here are based on general spec language in 11.5 Image Views section under
+    // vkCreateImageView(). What's the best way to create unique id for these cases?
     bool ds = vk_format_is_depth_or_stencil(format);
     switch (image_layout) {
     case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
@@ -713,7 +748,7 @@
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but does "
                                                         "not have VK_IMAGE_ASPECT_COLOR_BIT set.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // format must NOT be DS
@@ -722,7 +757,7 @@
             error_str << "ImageView (" << image_view
                       << ") uses layout VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL but the image format is "
                       << string_VkFormat(format) << " which is not a color format.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         break;
@@ -734,7 +769,7 @@
                 // both  must NOT be set
                 std::stringstream error_str;
                 error_str << "ImageView (" << image_view << ") has both STENCIL and DEPTH aspects set";
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
         } else if (!(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT)) {
@@ -742,7 +777,7 @@
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
                       << " but does not have STENCIL or DEPTH aspects set";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // format must be DS
@@ -750,12 +785,12 @@
             std::stringstream error_str;
             error_str << "ImageView (" << image_view << ") has layout " << string_VkImageLayout(image_layout)
                       << " but the image format is " << string_VkFormat(format) << " which is not a depth/stencil format.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         break;
     default:
-        // For other layouts if the source is ds image, both aspect bits must not be set
+        // For other layouts if the source is depth/stencil image, both aspect bits must not be set
         if (ds) {
             if (aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) {
                 if (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) {
@@ -767,7 +802,7 @@
                                  "image in a descriptor set, please only set either VK_IMAGE_ASPECT_DEPTH_BIT or "
                                  "VK_IMAGE_ASPECT_STENCIL_BIT depending on whether it will be used for depth reads or stencil "
                                  "reads respectively.";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             }
@@ -775,6 +810,11 @@
         break;
     }
     // Now validate that usage flags are correctly set for given type of update
+    //  As we're switching per-type, if any type has specific layout requirements, check those here as well
+    // TODO : The various image usage bit requirements are in general spec language for VkImageUsageFlags bit block in 11.3 Images
+    // under vkCreateImage()
+    // TODO : Need to also validate case VALIDATION_ERROR_00952 where STORAGE_IMAGE & INPUT_ATTACH types must have been created with
+    // identify swizzle
     std::string error_usage_bit;
     switch (type) {
     case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
@@ -787,6 +827,15 @@
     case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: {
         if (!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
             error_usage_bit = "VK_IMAGE_USAGE_STORAGE_BIT";
+        } else if (VK_IMAGE_LAYOUT_GENERAL != image_layout) {
+            std::stringstream error_str;
+            // TODO : Need to create custom enum error code for this case
+            error_str << "ImageView (" << image_view << ") of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout "
+                      << string_VkImageLayout(image_layout)
+                      << " but according to spec section 13.1 Descriptor Types, 'Load and store operations on storage images can "
+                         "only be done on images in VK_IMAGE_LAYOUT_GENERAL layout.'";
+            *error_msg = error_str.str();
+            return false;
         }
         break;
     }
@@ -804,7 +853,7 @@
         error_str << "ImageView (" << image_view << ") with usage mask 0x" << usage
                   << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
                   << error_usage_bit << " set.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     return true;
@@ -825,9 +874,9 @@
 
 void cvdescriptorset::SamplerDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) {
     if (!immutable_) {
-        auto sampler_node = getSamplerNode(dev_data, sampler_);
-        if (sampler_node)
-            core_validation::AddCommandBufferBindingSampler(cb_node, sampler_node);
+        auto sampler_state = getSamplerState(dev_data, sampler_);
+        if (sampler_state)
+            core_validation::AddCommandBufferBindingSampler(cb_node, sampler_state);
     }
 }
 
@@ -872,16 +921,14 @@
                                                                 GLOBAL_CB_NODE *cb_node) {
     // First add binding for any non-immutable sampler
     if (!immutable_) {
-        auto sampler_node = getSamplerNode(dev_data, sampler_);
-        if (sampler_node)
-            core_validation::AddCommandBufferBindingSampler(cb_node, sampler_node);
+        auto sampler_state = getSamplerState(dev_data, sampler_);
+        if (sampler_state)
+            core_validation::AddCommandBufferBindingSampler(cb_node, sampler_state);
     }
     // Add binding for image
-    auto iv_data = getImageViewData(dev_data, image_view_);
-    if (iv_data) {
-        auto image_node = getImageNode(dev_data, iv_data->image);
-        if (image_node)
-            core_validation::AddCommandBufferBindingImage(dev_data, cb_node, image_node);
+    auto iv_state = getImageViewState(dev_data, image_view_);
+    if (iv_state) {
+        core_validation::AddCommandBufferBindingImageView(dev_data, cb_node, iv_state);
     }
 }
 
@@ -910,11 +957,9 @@
 
 void cvdescriptorset::ImageDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) {
     // Add binding for image
-    auto iv_data = getImageViewData(dev_data, image_view_);
-    if (iv_data) {
-        auto image_node = getImageNode(dev_data, iv_data->image);
-        if (image_node)
-            core_validation::AddCommandBufferBindingImage(dev_data, cb_node, image_node);
+    auto iv_state = getImageViewState(dev_data, image_view_);
+    if (iv_state) {
+        core_validation::AddCommandBufferBindingImageView(dev_data, cb_node, iv_state);
     }
 }
 
@@ -971,11 +1016,9 @@
 }
 
 void cvdescriptorset::TexelDescriptor::BindCommandBuffer(const core_validation::layer_data *dev_data, GLOBAL_CB_NODE *cb_node) {
-    auto bv_info = getBufferViewInfo(dev_data, buffer_view_);
-    if (bv_info) {
-        auto buffer_node = getBufferNode(dev_data, bv_info->buffer);
-        if (buffer_node)
-            core_validation::AddCommandBufferBindingBuffer(dev_data, cb_node, buffer_node);
+    auto bv_state = getBufferViewState(dev_data, buffer_view_);
+    if (bv_state) {
+        core_validation::AddCommandBufferBindingBufferView(dev_data, cb_node, bv_state);
     }
 }
 
@@ -1000,13 +1043,14 @@
                         "Cannot call vkUpdateDescriptorSets() on descriptor set 0x%" PRIxLEAST64 " that has not been allocated.",
                         reinterpret_cast<uint64_t &>(dest_set));
         } else {
+            UNIQUE_VALIDATION_ERROR_CODE error_code;
             std::string error_str;
-            if (!set_node->ValidateWriteUpdate(report_data, &p_wds[i], &error_str)) {
+            if (!set_node->ValidateWriteUpdate(report_data, &p_wds[i], &error_code, &error_str)) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, DRAWSTATE_INVALID_WRITE_UPDATE, "DS",
+                                     reinterpret_cast<uint64_t &>(dest_set), __LINE__, error_code, "DS",
                                      "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x%" PRIx64
-                                     " with error: %s",
-                                     reinterpret_cast<uint64_t &>(dest_set), error_str.c_str());
+                                     " with error: %s. %s",
+                                     reinterpret_cast<uint64_t &>(dest_set), error_str.c_str(), validation_error_map[error_code]);
             }
         }
     }
@@ -1018,25 +1062,26 @@
         auto dst_node = core_validation::getSetNode(dev_data, dst_set);
         if (!src_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                 reinterpret_cast<uint64_t &>(src_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
+                                 reinterpret_cast<uint64_t &>(src_set), __LINE__, VALIDATION_ERROR_00971, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy from descriptor set 0x%" PRIxLEAST64
-                                 " that has not been allocated.",
-                                 reinterpret_cast<uint64_t &>(src_set));
+                                 " that has not been allocated. %s",
+                                 reinterpret_cast<uint64_t &>(src_set), validation_error_map[VALIDATION_ERROR_00971]);
         } else if (!dst_node) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                                 reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_DESCRIPTOR_SET, "DS",
+                                 reinterpret_cast<uint64_t &>(dst_set), __LINE__, VALIDATION_ERROR_00972, "DS",
                                  "Cannot call vkUpdateDescriptorSets() to copy to descriptor set 0x%" PRIxLEAST64
-                                 " that has not been allocated.",
-                                 reinterpret_cast<uint64_t &>(dst_set));
+                                 " that has not been allocated. %s",
+                                 reinterpret_cast<uint64_t &>(dst_set), validation_error_map[VALIDATION_ERROR_00972]);
         } else {
+            UNIQUE_VALIDATION_ERROR_CODE error_code;
             std::string error_str;
-            if (!dst_node->ValidateCopyUpdate(report_data, &p_cds[i], src_node, &error_str)) {
-                skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
-                            reinterpret_cast<uint64_t &>(dst_set), __LINE__, DRAWSTATE_INVALID_COPY_UPDATE, "DS",
-                            "vkUpdateDescriptorsSets() failed copy update from Descriptor Set 0x%" PRIx64
-                            " to Descriptor Set 0x%" PRIx64 " with error: %s",
-                            reinterpret_cast<uint64_t &>(src_set), reinterpret_cast<uint64_t &>(dst_set), error_str.c_str());
+            if (!dst_node->ValidateCopyUpdate(report_data, &p_cds[i], src_node, &error_code, &error_str)) {
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT,
+                                     reinterpret_cast<uint64_t &>(dst_set), __LINE__, error_code, "DS",
+                                     "vkUpdateDescriptorsSets() failed copy update from Descriptor Set 0x%" PRIx64
+                                     " to Descriptor Set 0x%" PRIx64 " with error: %s. %s",
+                                     reinterpret_cast<uint64_t &>(src_set), reinterpret_cast<uint64_t &>(dst_set),
+                                     error_str.c_str(), validation_error_map[error_code]);
             }
         }
     }
@@ -1074,9 +1119,11 @@
 // Validate the state for a given write update but don't actually perform the update
 //  If an error would occur for this update, return false and fill in details in error_msg string
 bool cvdescriptorset::DescriptorSet::ValidateWriteUpdate(const debug_report_data *report_data, const VkWriteDescriptorSet *update,
-                                                         std::string *error_msg) {
+                                                         UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) {
     // Verify idle ds
     if (in_use.load()) {
+        // TODO : Re-using Allocate Idle error code, need write update idle error code
+        *error_code = VALIDATION_ERROR_00919;
         std::stringstream error_str;
         error_str << "Cannot call vkUpdateDescriptorSets() to perform write update on descriptor set " << set_
                   << " that is in use by a command buffer.";
@@ -1085,6 +1132,7 @@
     }
     // Verify dst binding exists
     if (!p_layout_->HasBinding(update->dstBinding)) {
+        *error_code = VALIDATION_ERROR_00936;
         std::stringstream error_str;
         error_str << "DescriptorSet " << set_ << " does not have binding " << update->dstBinding << ".";
         *error_msg = error_str.str();
@@ -1094,6 +1142,7 @@
     auto start_idx = p_layout_->GetGlobalStartIndexFromBinding(update->dstBinding) + update->dstArrayElement;
     auto type = p_layout_->GetTypeFromBinding(update->dstBinding);
     if (type != update->descriptorType) {
+        *error_code = VALIDATION_ERROR_00937;
         std::stringstream error_str;
         error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with type "
                   << string_VkDescriptorType(type) << " but update type is " << string_VkDescriptorType(update->descriptorType);
@@ -1101,6 +1150,7 @@
         return false;
     }
     if ((start_idx + update->descriptorCount) > p_layout_->GetTotalDescriptorCount()) {
+        *error_code = VALIDATION_ERROR_00938;
         std::stringstream error_str;
         error_str << "Attempting write update to descriptor set " << set_ << " binding #" << update->dstBinding << " with "
                   << p_layout_->GetTotalDescriptorCount() << " total descriptors but update of " << update->descriptorCount
@@ -1112,10 +1162,12 @@
     }
     // Verify consecutive bindings match (if needed)
     if (!p_layout_->VerifyUpdateConsistency(update->dstBinding, update->dstArrayElement, update->descriptorCount, "write update to",
-                                            set_, error_msg))
+                                            set_, error_msg)) {
+        *error_code = VALIDATION_ERROR_00938;
         return false;
+    }
     // Update is within bounds and consistent so last step is to validate update contents
-    if (!VerifyWriteUpdateContents(update, start_idx, error_msg)) {
+    if (!VerifyWriteUpdateContents(update, start_idx, error_code, error_msg)) {
         std::stringstream error_str;
         error_str << "Write update to descriptor in set " << set_ << " binding #" << update->dstBinding
                   << " failed with error message: " << error_msg->c_str();
@@ -1126,32 +1178,36 @@
     return true;
 }
 // For the given buffer, verify that its creation parameters are appropriate for the given type
-//  If there's an error, update the error string with details and return false, else return true
+//  If there's an error, update the error_msg string with details and return false, else return true
 bool cvdescriptorset::DescriptorSet::ValidateBufferUsage(BUFFER_NODE const *buffer_node, VkDescriptorType type,
-                                                         std::string *error) const {
+                                                         UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) const {
     // Verify that usage bits set correctly for given type
     auto usage = buffer_node->createInfo.usage;
     std::string error_usage_bit;
     switch (type) {
     case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
         if (!(usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00950;
             error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
         if (!(usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00951;
             error_usage_bit = "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
     case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
         if (!(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00946;
             error_usage_bit = "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT";
         }
         break;
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
         if (!(usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) {
+            *error_code = VALIDATION_ERROR_00947;
             error_usage_bit = "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT";
         }
         break;
@@ -1163,7 +1219,7 @@
         error_str << "Buffer (" << buffer_node->buffer << ") with usage mask 0x" << usage
                   << " being used for a descriptor update of type " << string_VkDescriptorType(type) << " does not have "
                   << error_usage_bit << " set.";
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
     return true;
@@ -1173,46 +1229,56 @@
 //  2. buffer was created with correct usage flags
 //  3. offset is less than buffer size
 //  4. range is either VK_WHOLE_SIZE or falls in (0, (buffer size - offset)]
-// If there's an error, update the error string with details and return false, else return true
+// If there's an error, update the error_msg string with details and return false, else return true
 bool cvdescriptorset::DescriptorSet::ValidateBufferUpdate(VkDescriptorBufferInfo const *buffer_info, VkDescriptorType type,
-                                                          std::string *error) const {
+                                                          UNIQUE_VALIDATION_ERROR_CODE *error_code, std::string *error_msg) const {
+    // TODO : Defaulting to 00962 for all cases here. Need to create new error codes for a few cases below.
+    *error_code = VALIDATION_ERROR_00962;
     // First make sure that buffer is valid
     auto buffer_node = getBufferNode(device_data_, buffer_info->buffer);
     if (!buffer_node) {
         std::stringstream error_str;
         error_str << "Invalid VkBuffer: " << buffer_info->buffer;
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
-    if (ValidateMemoryIsBoundToBuffer(device_data_, buffer_node, "vkUpdateDescriptorSets()"))
+    if (ValidateMemoryIsBoundToBuffer(device_data_, buffer_node, "vkUpdateDescriptorSets()")) {
+        // TODO : This is a repeat code, need new code(s) for language in 11.6 Memory Association
+        *error_msg = "No memory bound to buffer.";
         return false;
+    }
     // Verify usage bits
-    if (!ValidateBufferUsage(buffer_node, type, error)) {
-        // error will have been updated by ValidateBufferUsage()
+    if (!ValidateBufferUsage(buffer_node, type, error_code, error_msg)) {
+        // error_msg will have been updated by ValidateBufferUsage()
         return false;
     }
+    // TODO : Need to also validate device limit offset requirements captured in VALIDATION_ERROR_00944,945
     // offset must be less than buffer size
     if (buffer_info->offset > buffer_node->createInfo.size) {
+        *error_code = VALIDATION_ERROR_00959;
         std::stringstream error_str;
         error_str << "VkDescriptorBufferInfo offset of " << buffer_info->offset << " is greater than buffer " << buffer_node->buffer
                   << " size of " << buffer_node->createInfo.size;
-        *error = error_str.str();
+        *error_msg = error_str.str();
         return false;
     }
+    // TODO : Need to also validate device limit range requirements captured in VALIDATION_ERROR_00948,949
     if (buffer_info->range != VK_WHOLE_SIZE) {
         // Range must be VK_WHOLE_SIZE or > 0
         if (!buffer_info->range) {
+            *error_code = VALIDATION_ERROR_00960;
             std::stringstream error_str;
             error_str << "VkDescriptorBufferInfo range is not VK_WHOLE_SIZE and is zero, which is not allowed.";
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
         // Range must be VK_WHOLE_SIZE or <= (buffer size - offset)
         if (buffer_info->range > (buffer_node->createInfo.size - buffer_info->offset)) {
+            *error_code = VALIDATION_ERROR_00961;
             std::stringstream error_str;
             error_str << "VkDescriptorBufferInfo range is " << buffer_info->range << " which is greater than buffer size ("
                       << buffer_node->createInfo.size << ") minus requested offset of " << buffer_info->offset;
-            *error = error_str.str();
+            *error_msg = error_str.str();
             return false;
         }
     }
@@ -1221,17 +1287,18 @@
 
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyWriteUpdateContents(const VkWriteDescriptorSet *update, const uint32_t index,
-                                                               std::string *error) const {
+                                                               UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                               std::string *error_msg) const {
     switch (update->descriptorType) {
     case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             // Validate image
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to combined image sampler descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1241,10 +1308,11 @@
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!descriptors_[index + di].get()->IsImmutableSampler()) {
                 if (!ValidateSampler(update->pImageInfo[di].sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted write update to sampler descriptor with invalid sampler: "
                               << update->pImageInfo[di].sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1259,10 +1327,10 @@
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto image_view = update->pImageInfo[di].imageView;
             auto image_layout = update->pImageInfo[di].imageLayout;
-            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, update->descriptorType, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to image descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to image descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1272,18 +1340,19 @@
     case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer_view = update->pTexelBufferView[di];
-            auto bv_info = getBufferViewInfo(device_data_, buffer_view);
-            if (!bv_info) {
+            auto bv_state = getBufferViewState(device_data_, buffer_view);
+            if (!bv_state) {
+                *error_code = VALIDATION_ERROR_00940;
                 std::stringstream error_str;
                 error_str << "Attempted write update to texel buffer descriptor with invalid buffer view: " << buffer_view;
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
-            auto buffer = bv_info->buffer;
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), update->descriptorType, error)) {
+            auto buffer = bv_state->create_info.buffer;
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), update->descriptorType, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to texel buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to texel buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1294,10 +1363,10 @@
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
     case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
-            if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, error)) {
+            if (!ValidateBufferUpdate(update->pBufferInfo + di, update->descriptorType, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted write update to buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted write update to buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1312,16 +1381,21 @@
 }
 // Verify that the contents of the update are ok, but don't perform actual update
 bool cvdescriptorset::DescriptorSet::VerifyCopyUpdateContents(const VkCopyDescriptorSet *update, const DescriptorSet *src_set,
-                                                              VkDescriptorType type, uint32_t index, std::string *error) const {
+                                                              VkDescriptorType type, uint32_t index,
+                                                              UNIQUE_VALIDATION_ERROR_CODE *error_code,
+                                                              std::string *error_msg) const {
+    // Note : Repurposing some Write update error codes here as specific details aren't called out for copy updates like they are
+    // for write updates
     switch (src_set->descriptors_[index]->descriptor_class) {
     case PlainSampler: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             if (!src_set->descriptors_[index + di]->IsImmutableSampler()) {
                 auto update_sampler = static_cast<SamplerDescriptor *>(src_set->descriptors_[index + di].get())->GetSampler();
                 if (!ValidateSampler(update_sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1337,9 +1411,10 @@
             if (!img_samp_desc->IsImmutableSampler()) {
                 auto update_sampler = img_samp_desc->GetSampler();
                 if (!ValidateSampler(update_sampler, device_data_)) {
+                    *error_code = VALIDATION_ERROR_00942;
                     std::stringstream error_str;
                     error_str << "Attempted copy update to sampler descriptor with invalid sampler: " << update_sampler << ".";
-                    *error = error_str.str();
+                    *error_msg = error_str.str();
                     return false;
                 }
             } else {
@@ -1348,23 +1423,24 @@
             // Validate image
             auto image_view = img_samp_desc->GetImageView();
             auto image_layout = img_samp_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to combined image sampler descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to combined image sampler descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
+        break;
     }
     case Image: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto img_desc = static_cast<const ImageDescriptor *>(src_set->descriptors_[index + di].get());
             auto image_view = img_desc->GetImageView();
             auto image_layout = img_desc->GetImageLayout();
-            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error)) {
+            if (!ValidateImageUpdate(image_view, image_layout, type, device_data_, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to image descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to image descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1373,18 +1449,19 @@
     case TexelBuffer: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer_view = static_cast<TexelDescriptor *>(src_set->descriptors_[index + di].get())->GetBufferView();
-            auto bv_info = getBufferViewInfo(device_data_, buffer_view);
-            if (!bv_info) {
+            auto bv_state = getBufferViewState(device_data_, buffer_view);
+            if (!bv_state) {
+                *error_code = VALIDATION_ERROR_00940;
                 std::stringstream error_str;
                 error_str << "Attempted copy update to texel buffer descriptor with invalid buffer view: " << buffer_view;
-                *error = error_str.str();
+                *error_msg = error_str.str();
                 return false;
             }
-            auto buffer = bv_info->buffer;
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
+            auto buffer = bv_state->create_info.buffer;
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to texel buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1393,10 +1470,10 @@
     case GeneralBuffer: {
         for (uint32_t di = 0; di < update->descriptorCount; ++di) {
             auto buffer = static_cast<BufferDescriptor *>(src_set->descriptors_[index + di].get())->GetBuffer();
-            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error)) {
+            if (!ValidateBufferUsage(getBufferNode(device_data_, buffer), type, error_code, error_msg)) {
                 std::stringstream error_str;
-                error_str << "Attempted copy update to buffer descriptor failed due to: " << error->c_str();
-                *error = error_str.str();
+                error_str << "Attempted copy update to buffer descriptor failed due to: " << error_msg->c_str();
+                *error_msg = error_str.str();
                 return false;
             }
         }
@@ -1434,24 +1511,24 @@
             }
         }
     }
-    auto pool_node = getPoolNode(dev_data, p_alloc_info->descriptorPool);
+    auto pool_state = getDescriptorPoolState(dev_data, p_alloc_info->descriptorPool);
     // Track number of descriptorSets allowable in this pool
-    if (pool_node->availableSets < p_alloc_info->descriptorSetCount) {
+    if (pool_state->availableSets < p_alloc_info->descriptorSetCount) {
         skip_call |= log_msg(
             report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-            reinterpret_cast<uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
+            reinterpret_cast<uint64_t &>(pool_state->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY, "DS",
             "Unable to allocate %u descriptorSets from pool 0x%" PRIxLEAST64 ". This pool only has %d descriptorSets remaining.",
-            p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableSets);
+            p_alloc_info->descriptorSetCount, reinterpret_cast<uint64_t &>(pool_state->pool), pool_state->availableSets);
     }
     // Determine whether descriptor counts are satisfiable
     for (uint32_t i = 0; i < VK_DESCRIPTOR_TYPE_RANGE_SIZE; i++) {
-        if (ds_data->required_descriptors_by_type[i] > pool_node->availableDescriptorTypeCount[i]) {
+        if (ds_data->required_descriptors_by_type[i] > pool_state->availableDescriptorTypeCount[i]) {
             skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT,
-                                 reinterpret_cast<const uint64_t &>(pool_node->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
+                                 reinterpret_cast<const uint64_t &>(pool_state->pool), __LINE__, DRAWSTATE_DESCRIPTOR_POOL_EMPTY,
                                  "DS", "Unable to allocate %u descriptors of type %s from pool 0x%" PRIxLEAST64
                                        ". This pool only has %d descriptors of this type remaining.",
                                  ds_data->required_descriptors_by_type[i], string_VkDescriptorType(VkDescriptorType(i)),
-                                 reinterpret_cast<uint64_t &>(pool_node->pool), pool_node->availableDescriptorTypeCount[i]);
+                                 reinterpret_cast<uint64_t &>(pool_state->pool), pool_state->availableDescriptorTypeCount[i]);
         }
     }
 
@@ -1461,7 +1538,7 @@
 void cvdescriptorset::PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *p_alloc_info,
                                                     const VkDescriptorSet *descriptor_sets,
                                                     const AllocateDescriptorSetsData *ds_data,
-                                                    std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *pool_map,
+                                                    std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_STATE *> *pool_map,
                                                     std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *set_map,
                                                     const core_validation::layer_data *dev_data) {
     auto pool_state = (*pool_map)[p_alloc_info->descriptorPool];
@@ -1474,7 +1551,8 @@
      * global map and the pool's set.
      */
     for (uint32_t i = 0; i < p_alloc_info->descriptorSetCount; i++) {
-        auto new_ds = new cvdescriptorset::DescriptorSet(descriptor_sets[i], ds_data->layout_nodes[i], dev_data);
+        auto new_ds = new cvdescriptorset::DescriptorSet(descriptor_sets[i], p_alloc_info->descriptorPool, ds_data->layout_nodes[i],
+                                                         dev_data);
 
         pool_state->sets.insert(new_ds);
         new_ds->in_use.store(0);
diff --git a/layers/descriptor_sets.h b/layers/descriptor_sets.h
index aeb071d..2cf45e7 100644
--- a/layers/descriptor_sets.h
+++ b/layers/descriptor_sets.h
@@ -21,6 +21,7 @@
 #define CORE_VALIDATION_DESCRIPTOR_SETS_H_
 
 // Check for noexcept support
+#ifndef NOEXCEPT
 #if defined(__clang__)
 #if __has_feature(cxx_noexcept)
 #define HAS_NOEXCEPT
@@ -40,8 +41,10 @@
 #else
 #define NOEXCEPT
 #endif
+#endif
 
 #include "core_validation_error_enums.h"
+#include "vk_validation_error_messages.h"
 #include "core_validation_types.h"
 #include "vk_layer_logging.h"
 #include "vk_layer_utils.h"
@@ -86,8 +89,9 @@
 class DescriptorSetLayout {
   public:
     // Constructors and destructor
-    DescriptorSetLayout(debug_report_data *report_data, const VkDescriptorSetLayoutCreateInfo *p_create_info,
-                        const VkDescriptorSetLayout layout);
+    DescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo *p_create_info, const VkDescriptorSetLayout layout);
+    // Validate create info - should be called prior to creation
+    static bool ValidateCreateInfo(debug_report_data *, const VkDescriptorSetLayoutCreateInfo *);
     // Straightforward Get functions
     VkDescriptorSetLayout GetDescriptorSetLayout() const { return layout_; };
     uint32_t GetTotalDescriptorCount() const { return descriptor_count_; };
@@ -165,7 +169,8 @@
 // Shared helper functions - These are useful because the shared sampler image descriptor type
 //  performs common functions with both sampler and image descriptors so they can share their common functions
 bool ValidateSampler(const VkSampler, const core_validation::layer_data *);
-bool ValidateImageUpdate(VkImageView, VkImageLayout, VkDescriptorType, const core_validation::layer_data *, std::string *);
+bool ValidateImageUpdate(VkImageView, VkImageLayout, VkDescriptorType, const core_validation::layer_data *,
+                         UNIQUE_VALIDATION_ERROR_CODE *, std::string *);
 
 class SamplerDescriptor : public Descriptor {
   public:
@@ -269,7 +274,7 @@
                                     const core_validation::layer_data *, AllocateDescriptorSetsData *);
 // Update state based on allocating new descriptorsets
 void PerformAllocateDescriptorSets(const VkDescriptorSetAllocateInfo *, const VkDescriptorSet *, const AllocateDescriptorSetsData *,
-                                   std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_NODE *> *,
+                                   std::unordered_map<VkDescriptorPool, DESCRIPTOR_POOL_STATE *> *,
                                    std::unordered_map<VkDescriptorSet, cvdescriptorset::DescriptorSet *> *,
                                    const core_validation::layer_data *);
 
@@ -293,9 +298,7 @@
  */
 class DescriptorSet : public BASE_NODE {
   public:
-    using BASE_NODE::in_use;
-    using BASE_NODE::cb_bindings;
-    DescriptorSet(const VkDescriptorSet, const DescriptorSetLayout *, const core_validation::layer_data *);
+    DescriptorSet(const VkDescriptorSet, const VkDescriptorPool, const DescriptorSetLayout *, const core_validation::layer_data *);
     ~DescriptorSet();
     // A number of common Get* functions that return data based on layout from which this set was created
     uint32_t GetTotalDescriptorCount() const { return p_layout_ ? p_layout_->GetTotalDescriptorCount() : 0; };
@@ -329,11 +332,13 @@
 
     // Descriptor Update functions. These functions validate state and perform update separately
     // Validate contents of a WriteUpdate
-    bool ValidateWriteUpdate(const debug_report_data *, const VkWriteDescriptorSet *, std::string *);
+    bool ValidateWriteUpdate(const debug_report_data *, const VkWriteDescriptorSet *, UNIQUE_VALIDATION_ERROR_CODE *,
+                             std::string *);
     // Perform a WriteUpdate whose contents were just validated using ValidateWriteUpdate
     void PerformWriteUpdate(const VkWriteDescriptorSet *);
     // Validate contents of a CopyUpdate
-    bool ValidateCopyUpdate(const debug_report_data *, const VkCopyDescriptorSet *, const DescriptorSet *, std::string *);
+    bool ValidateCopyUpdate(const debug_report_data *, const VkCopyDescriptorSet *, const DescriptorSet *,
+                            UNIQUE_VALIDATION_ERROR_CODE *, std::string *);
     // Perform a CopyUpdate whose contents were just validated using ValidateCopyUpdate
     void PerformCopyUpdate(const VkCopyDescriptorSet *, const DescriptorSet *);
 
@@ -359,15 +364,18 @@
     bool IsUpdated() const { return some_update_; };
 
   private:
-    bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, std::string *) const;
+    bool VerifyWriteUpdateContents(const VkWriteDescriptorSet *, const uint32_t, UNIQUE_VALIDATION_ERROR_CODE *,
+                                   std::string *) const;
     bool VerifyCopyUpdateContents(const VkCopyDescriptorSet *, const DescriptorSet *, VkDescriptorType, uint32_t,
-                                  std::string *) const;
-    bool ValidateBufferUsage(BUFFER_NODE const *, VkDescriptorType, std::string *) const;
-    bool ValidateBufferUpdate(VkDescriptorBufferInfo const *, VkDescriptorType, std::string *) const;
+                                  UNIQUE_VALIDATION_ERROR_CODE *, std::string *) const;
+    bool ValidateBufferUsage(BUFFER_NODE const *, VkDescriptorType, UNIQUE_VALIDATION_ERROR_CODE *, std::string *) const;
+    bool ValidateBufferUpdate(VkDescriptorBufferInfo const *, VkDescriptorType, UNIQUE_VALIDATION_ERROR_CODE *,
+                              std::string *) const;
     // Private helper to set all bound cmd buffers to INVALID state
     void InvalidateBoundCmdBuffers();
     bool some_update_; // has any part of the set ever been updated?
     VkDescriptorSet set_;
+    DESCRIPTOR_POOL_STATE *pool_state_;
     const DescriptorSetLayout *p_layout_;
     std::vector<std::unique_ptr<Descriptor>> descriptors_;
     // Ptr to device data used for various data look-ups
diff --git a/layers/image.cpp b/layers/image.cpp
index 472de93..383693d 100644
--- a/layers/image.cpp
+++ b/layers/image.cpp
@@ -47,6 +47,7 @@
 #include "vk_layer_extension_utils.h"
 #include "vk_layer_utils.h"
 #include "vk_layer_logging.h"
+#include "vk_validation_error_messages.h"
 
 using namespace std;
 
@@ -690,7 +691,7 @@
 }
 
 // Returns true if [x, xoffset] and [y, yoffset] overlap
-static bool ranges_intersect(int32_t start, uint32_t start_offset, int32_t end, uint32_t end_offset) {
+static bool RangesIntersect(int32_t start, uint32_t start_offset, int32_t end, uint32_t end_offset) {
     bool result = false;
     uint32_t intersection_min = std::max(static_cast<uint32_t>(start), static_cast<uint32_t>(end));
     uint32_t intersection_max = std::min(static_cast<uint32_t>(start) + start_offset, static_cast<uint32_t>(end) + end_offset);
@@ -702,21 +703,21 @@
 }
 
 // Returns true if two VkImageCopy structures overlap
-static bool region_intersects(const VkImageCopy *src, const VkImageCopy *dst, VkImageType type) {
+static bool RegionIntersects(const VkImageCopy *src, const VkImageCopy *dst, VkImageType type) {
     bool result = true;
     if ((src->srcSubresource.mipLevel == dst->dstSubresource.mipLevel) &&
-        (ranges_intersect(src->srcSubresource.baseArrayLayer, src->srcSubresource.layerCount, dst->dstSubresource.baseArrayLayer,
-                          dst->dstSubresource.layerCount))) {
+        (RangesIntersect(src->srcSubresource.baseArrayLayer, src->srcSubresource.layerCount, dst->dstSubresource.baseArrayLayer,
+                         dst->dstSubresource.layerCount))) {
 
         switch (type) {
         case VK_IMAGE_TYPE_3D:
-            result &= ranges_intersect(src->srcOffset.z, src->extent.depth, dst->dstOffset.z, dst->extent.depth);
+            result &= RangesIntersect(src->srcOffset.z, src->extent.depth, dst->dstOffset.z, dst->extent.depth);
         // Intentionally fall through to 2D case
         case VK_IMAGE_TYPE_2D:
-            result &= ranges_intersect(src->srcOffset.y, src->extent.height, dst->dstOffset.y, dst->extent.height);
+            result &= RangesIntersect(src->srcOffset.y, src->extent.height, dst->dstOffset.y, dst->extent.height);
         // Intentionally fall through to 1D case
         case VK_IMAGE_TYPE_1D:
-            result &= ranges_intersect(src->srcOffset.x, src->extent.width, dst->dstOffset.x, dst->extent.width);
+            result &= RangesIntersect(src->srcOffset.x, src->extent.width, dst->dstOffset.x, dst->extent.width);
             break;
         default:
             // Unrecognized or new IMAGE_TYPE enums will be caught in parameter_validation
@@ -727,189 +728,213 @@
 }
 
 // Returns true if offset and extent exceed image extents
-static bool exceeds_bounds(const VkOffset3D *offset, const VkExtent3D *extent, const IMAGE_STATE *image) {
+static bool ExceedsBounds(const VkOffset3D *offset, const VkExtent3D *extent, const IMAGE_STATE *image) {
     bool result = false;
     // Extents/depths cannot be negative but checks left in for clarity
-
+    switch (image->imageType) {
+    case VK_IMAGE_TYPE_3D: // Validate z and depth
+        if ((offset->z + extent->depth > image->extent.depth) || (offset->z < 0) ||
+            ((offset->z + static_cast<int32_t>(extent->depth)) < 0)) {
+            result = true;
+        }
+        // Intentionally fall through to 2D case to check height
+    case VK_IMAGE_TYPE_2D: // Validate y and height
+        if ((offset->y + extent->height > image->extent.height) || (offset->y < 0) ||
+            ((offset->y + static_cast<int32_t>(extent->height)) < 0)) {
+            result = true;
+        }
+        // Intentionally fall through to 1D case to check width
+    case VK_IMAGE_TYPE_1D: // Validate x and width
+        if ((offset->x + extent->width > image->extent.width) || (offset->x < 0) ||
+            ((offset->x + static_cast<int32_t>(extent->width)) < 0)) {
+            result = true;
+        }
+        break;
+    default:
+        assert(false);
+    }
     return result;
 }
 
-bool cmd_copy_image_valid_usage(VkCommandBuffer commandBuffer, VkImage srcImage, VkImage dstImage, uint32_t regionCount,
-                                const VkImageCopy *pRegions) {
-
-    bool skipCall = false;
-    layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
-    auto srcImageEntry = getImageState(device_data, srcImage);
-    auto dstImageEntry = getImageState(device_data, dstImage);
+bool PreCallValidateCmdCopyImage(VkCommandBuffer command_buffer, VkImage src_image, VkImage dst_image, uint32_t region_count,
+                                 const VkImageCopy *regions) {
+    bool skip = false;
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(command_buffer), layer_data_map);
+    auto src_image_entry = getImageState(device_data, src_image);
+    auto dst_image_entry = getImageState(device_data, dst_image);
 
     // TODO: This does not cover swapchain-created images. This should fall out when this layer is moved
     // into the core_validation layer
-    if (srcImageEntry && dstImageEntry) {
+    if (src_image_entry && dst_image_entry) {
 
-        for (uint32_t i = 0; i < regionCount; i++) {
+        for (uint32_t i = 0; i < region_count; i++) {
 
-            if (pRegions[i].srcSubresource.layerCount == 0) {
+            if (regions[i].srcSubresource.layerCount == 0) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] srcSubresource is zero";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
             }
 
-            if (pRegions[i].dstSubresource.layerCount == 0) {
+            if (regions[i].dstSubresource.layerCount == 0) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: number of layers in pRegions[" << i << "] dstSubresource is zero";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
             }
 
             // For each region the layerCount member of srcSubresource and dstSubresource must match
-            if (pRegions[i].srcSubresource.layerCount != pRegions[i].dstSubresource.layerCount) {
+            if (regions[i].srcSubresource.layerCount != regions[i].dstSubresource.layerCount) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: number of layers in source and destination subresources for pRegions[" << i
                    << "] do not match";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |=
+                    log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01198, "IMAGE", "%s. %s",
+                            ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01198]);
             }
 
             // For each region, the aspectMask member of srcSubresource and dstSubresource must match
-            if (pRegions[i].srcSubresource.aspectMask != pRegions[i].dstSubresource.aspectMask) {
+            if (regions[i].srcSubresource.aspectMask != regions[i].dstSubresource.aspectMask) {
                 char const str[] = "vkCmdCopyImage: Src and dest aspectMasks for each region must match";
-                skipCall |=
+                skip |=
                     log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, IMAGE_MISMATCHED_IMAGE_ASPECT, "IMAGE", str);
             }
 
             // AspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT
-            if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) ||
-                (pRegions[i].dstSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) {
+            if ((regions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT) ||
+                (regions[i].dstSubresource.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: pRegions[" << i << "] may not specify aspectMask containing VK_IMAGE_ASPECT_METADATA_BIT";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", "%s", ss.str().c_str());
             }
 
             // For each region, if aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of
             // VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT
-            if ((pRegions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
-                (pRegions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
+            if ((regions[i].srcSubresource.aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) &&
+                (regions[i].srcSubresource.aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))) {
                 char const str[] = "vkCmdCopyImage aspectMask cannot specify both COLOR and DEPTH/STENCIL aspects";
-                skipCall |=
+                skip |=
                     log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, IMAGE_INVALID_IMAGE_ASPECT, "IMAGE", str);
             }
 
-            // If either of the calling command's srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D,
+            // If either of the calling command's src_image or dst_image parameters are of VkImageType VK_IMAGE_TYPE_3D,
             // the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively
-            if (((srcImageEntry->imageType == VK_IMAGE_TYPE_3D) || (dstImageEntry->imageType == VK_IMAGE_TYPE_3D)) &&
-                ((pRegions[i].srcSubresource.baseArrayLayer != 0) || (pRegions[i].srcSubresource.layerCount != 1) ||
-                 (pRegions[i].dstSubresource.baseArrayLayer != 0) || (pRegions[i].dstSubresource.layerCount != 1))) {
+            if (((src_image_entry->imageType == VK_IMAGE_TYPE_3D) || (dst_image_entry->imageType == VK_IMAGE_TYPE_3D)) &&
+                ((regions[i].srcSubresource.baseArrayLayer != 0) || (regions[i].srcSubresource.layerCount != 1) ||
+                 (regions[i].dstSubresource.baseArrayLayer != 0) || (regions[i].dstSubresource.layerCount != 1))) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: src or dstImage type was IMAGE_TYPE_3D, but in subRegion[" << i
                    << "] baseArrayLayer was not zero or layerCount was not 1.";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
             }
 
             // MipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created
-            if (pRegions[i].srcSubresource.mipLevel >= srcImageEntry->mipLevels) {
+            if (regions[i].srcSubresource.mipLevel >= src_image_entry->mipLevels) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: pRegions[" << i
                    << "] specifies a src mipLevel greater than the number specified when the srcImage was created.";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
             }
-            if (pRegions[i].dstSubresource.mipLevel >= dstImageEntry->mipLevels) {
+            if (regions[i].dstSubresource.mipLevel >= dst_image_entry->mipLevels) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: pRegions[" << i
                    << "] specifies a dst mipLevel greater than the number specified when the dstImage was created.";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
             }
 
             // (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the
             // image was created
-            if ((pRegions[i].srcSubresource.baseArrayLayer + pRegions[i].srcSubresource.layerCount) > srcImageEntry->arraySize) {
+            if ((regions[i].srcSubresource.baseArrayLayer + regions[i].srcSubresource.layerCount) > src_image_entry->arraySize) {
                 std::stringstream ss;
-                ss << "vkCmdCopyImage: srcImage arrayLayers was " << srcImageEntry->arraySize << " but subRegion[" << i
+                ss << "vkCmdCopyImage: srcImage arrayLayers was " << src_image_entry->arraySize << " but subRegion[" << i
                    << "] baseArrayLayer + layerCount is "
-                   << (pRegions[i].srcSubresource.baseArrayLayer + pRegions[i].srcSubresource.layerCount);
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                   << (regions[i].srcSubresource.baseArrayLayer + regions[i].srcSubresource.layerCount);
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
             }
-            if ((pRegions[i].dstSubresource.baseArrayLayer + pRegions[i].dstSubresource.layerCount) > dstImageEntry->arraySize) {
+            if ((regions[i].dstSubresource.baseArrayLayer + regions[i].dstSubresource.layerCount) > dst_image_entry->arraySize) {
                 std::stringstream ss;
-                ss << "vkCmdCopyImage: dstImage arrayLayers was " << dstImageEntry->arraySize << " but subRegion[" << i
+                ss << "vkCmdCopyImage: dstImage arrayLayers was " << dst_image_entry->arraySize << " but subRegion[" << i
                    << "] baseArrayLayer + layerCount is "
-                   << (pRegions[i].dstSubresource.baseArrayLayer + pRegions[i].dstSubresource.layerCount);
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                   << (regions[i].dstSubresource.baseArrayLayer + regions[i].dstSubresource.layerCount);
+                skip |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
+                                __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
             }
 
-            // The source region specified by a given element of pRegions must be a region that is contained within srcImage
-            if (exceeds_bounds(&pRegions[i].srcOffset, &pRegions[i].extent, srcImageEntry)) {
+            // The source region specified by a given element of regions must be a region that is contained within srcImage
+            if (ExceedsBounds(&regions[i].srcOffset, &regions[i].extent, src_image_entry)) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: srcSubResource in pRegions[" << i << "] exceeds extents srcImage was created with";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |=
+                    log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01175, "IMAGE", "%s. %s",
+                            ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01175]);
             }
 
-            // The destination region specified by a given element of pRegions must be a region that is contained within dstImage
-            if (exceeds_bounds(&pRegions[i].dstOffset, &pRegions[i].extent, dstImageEntry)) {
+            // The destination region specified by a given element of regions must be a region that is contained within dst_image
+            if (ExceedsBounds(&regions[i].dstOffset, &regions[i].extent, dst_image_entry)) {
                 std::stringstream ss;
                 ss << "vkCmdCopyImage: dstSubResource in pRegions[" << i << "] exceeds extents dstImage was created with";
-                skipCall |= log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
-                                    __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
+                skip |=
+                    log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01176, "IMAGE", "%s. %s",
+                            ss.str().c_str(), validation_error_map[VALIDATION_ERROR_01176]);
             }
 
-            // The union of all source regions, and the union of all destination regions, specified by the elements of pRegions,
+            // The union of all source regions, and the union of all destination regions, specified by the elements of regions,
             // must not overlap in memory
-            if (srcImage == dstImage) {
-                for (uint32_t j = 0; j < regionCount; j++) {
-                    if (region_intersects(&pRegions[i], &pRegions[j], srcImageEntry->imageType)) {
+            if (src_image == dst_image) {
+                for (uint32_t j = 0; j < region_count; j++) {
+                    if (RegionIntersects(&regions[i], &regions[j], src_image_entry->imageType)) {
                         std::stringstream ss;
                         ss << "vkCmdCopyImage: pRegions[" << i << "] src overlaps with pRegions[" << j << "].";
-                        skipCall |=
+                        skip |=
                             log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(commandBuffer),
+                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, reinterpret_cast<uint64_t &>(command_buffer),
                                     __LINE__, IMAGE_INVALID_EXTENTS, "IMAGE", "%s", ss.str().c_str());
                     }
                 }
             }
         }
 
-        // The formats of srcImage and dstImage must be compatible. Formats are considered compatible if their texel size in bytes
+        // The formats of src_image and dst_image must be compatible. Formats are considered compatible if their texel size in bytes
         // is the same between both formats. For example, VK_FORMAT_R8G8B8A8_UNORM is compatible with VK_FORMAT_R32_UINT because
         // because both texels are 4 bytes in size. Depth/stencil formats must match exactly.
-        if (vk_format_is_depth_or_stencil(srcImageEntry->format) || vk_format_is_depth_or_stencil(dstImageEntry->format)) {
-            if (srcImageEntry->format != dstImageEntry->format) {
+        if (vk_format_is_depth_or_stencil(src_image_entry->format) || vk_format_is_depth_or_stencil(dst_image_entry->format)) {
+            if (src_image_entry->format != dst_image_entry->format) {
                 char const str[] = "vkCmdCopyImage called with unmatched source and dest image depth/stencil formats.";
-                skipCall |=
+                skip |=
                     log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
             }
         } else {
-            size_t srcSize = vk_format_get_size(srcImageEntry->format);
-            size_t destSize = vk_format_get_size(dstImageEntry->format);
+            size_t srcSize = vk_format_get_size(src_image_entry->format);
+            size_t destSize = vk_format_get_size(dst_image_entry->format);
             if (srcSize != destSize) {
                 char const str[] = "vkCmdCopyImage called with unmatched source and dest image format sizes.";
-                skipCall |=
+                skip |=
                     log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
-                            reinterpret_cast<uint64_t &>(commandBuffer), __LINE__, IMAGE_MISMATCHED_IMAGE_FORMAT, "IMAGE", str);
+                            reinterpret_cast<uint64_t &>(command_buffer), __LINE__, VALIDATION_ERROR_01184, "IMAGE", "%s. %s", str,
+                            validation_error_map[VALIDATION_ERROR_01184]);
             }
         }
     }
-    return skipCall;
+    return skip;
 }
 
 VKAPI_ATTR void VKAPI_CALL CmdCopyImage(VkCommandBuffer commandBuffer, VkImage srcImage,
@@ -917,12 +942,12 @@
                                         VkImageLayout dstImageLayout, uint32_t regionCount,
                                         const VkImageCopy *pRegions) {
 
-    bool skipCall = false;
+    bool skip = false;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
 
-    skipCall = cmd_copy_image_valid_usage(commandBuffer, srcImage, dstImage, regionCount, pRegions);
+    skip = PreCallValidateCmdCopyImage(commandBuffer, srcImage, dstImage, regionCount, pRegions);
 
-    if (!skipCall) {
+    if (!skip) {
         device_data->device_dispatch_table->CmdCopyImage(commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout,
                                                          regionCount, pRegions);
     }
diff --git a/layers/image.h b/layers/image.h
index 6a6c76b..c225ea4 100644
--- a/layers/image.h
+++ b/layers/image.h
@@ -30,8 +30,8 @@
     IMAGE_NONE,                             // Used for INFO & other non-error messages
     IMAGE_FORMAT_UNSUPPORTED,               // Request to create Image or RenderPass with a format that is not supported
     IMAGE_RENDERPASS_INVALID_ATTACHMENT,    // Invalid image layouts and/or load/storeOps for an attachment when creating RenderPass
-    IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, // If no depth attachment for a RenderPass, verify that subpass DS attachment is set to
-                                            // UNUSED
+    IMAGE_RENDERPASS_INVALID_DS_ATTACHMENT, // If no depth/stencil attachment for a RenderPass, verify that subpass DS attachment
+                                            // is set to UNUSED
     IMAGE_INVALID_IMAGE_ASPECT,             // Image aspect mask bits are invalid for this API call
     IMAGE_MISMATCHED_IMAGE_ASPECT,          // Image aspect masks for source and dest images do not match
     IMAGE_VIEW_CREATE_ERROR,                // Error occurred trying to create Image View
diff --git a/layers/linux/VkLayer_core_validation.json b/layers/linux/VkLayer_core_validation.json
index 208a195..5e36473 100644
--- a/layers/linux/VkLayer_core_validation.json
+++ b/layers/linux/VkLayer_core_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_core_validation.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_image.json b/layers/linux/VkLayer_image.json
index c8c8afd..58e2368 100644
--- a/layers/linux/VkLayer_image.json
+++ b/layers/linux/VkLayer_image.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_image.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_object_tracker.json b/layers/linux/VkLayer_object_tracker.json
index 9a32d4d..f133526 100644
--- a/layers/linux/VkLayer_object_tracker.json
+++ b/layers/linux/VkLayer_object_tracker.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_object_tracker.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_parameter_validation.json b/layers/linux/VkLayer_parameter_validation.json
index 8b716e3..48fed8e 100644
--- a/layers/linux/VkLayer_parameter_validation.json
+++ b/layers/linux/VkLayer_parameter_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_parameter_validation.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_swapchain.json b/layers/linux/VkLayer_swapchain.json
index 8f37072..fc7ea6e 100644
--- a/layers/linux/VkLayer_swapchain.json
+++ b/layers/linux/VkLayer_swapchain.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_swapchain.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_threading.json b/layers/linux/VkLayer_threading.json
index e3a15fb..ce9b039 100644
--- a/layers/linux/VkLayer_threading.json
+++ b/layers/linux/VkLayer_threading.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_threading.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
diff --git a/layers/linux/VkLayer_unique_objects.json b/layers/linux/VkLayer_unique_objects.json
index 1704d93..34d6230 100644
--- a/layers/linux/VkLayer_unique_objects.json
+++ b/layers/linux/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": "./libVkLayer_unique_objects.so",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/layers/object_tracker.cpp b/layers/object_tracker.cpp
index 3c906ac..ec1bcae 100644
--- a/layers/object_tracker.cpp
+++ b/layers/object_tracker.cpp
@@ -42,6 +42,8 @@
 
 #include "object_tracker.h"
 
+#include "vk_validation_error_messages.h"
+
 namespace object_tracker {
 
 static void InitObjectTracker(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
@@ -242,76 +244,41 @@
     device_data->swapchainImageMap[reinterpret_cast<uint64_t &>(swapchain_image)] = pNewObjNode;
 }
 
+template<typename T>
+uint64_t handle_value(T handle) {
+    return reinterpret_cast<uint64_t &>(handle);
+}
+template<typename T>
+uint64_t handle_value(T *handle) {
+    return reinterpret_cast<uint64_t>(handle);
+}
+
 template <typename T1, typename T2>
-static void CreateDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+static void CreateObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type, const VkAllocationCallbacks *pAllocator) {
     layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
 
-    log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<uint64_t>(object),
+    auto object_handle = handle_value(object);
+    bool custom_allocator = pAllocator != nullptr;
+
+    log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, object_handle,
             __LINE__, OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            object_name[object_type], reinterpret_cast<uint64_t>(object));
+            object_name[object_type], object_handle);
 
     OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
     pNewObjNode->object_type = object_type;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->handle = reinterpret_cast<uint64_t>(object);
-    instance_data->object_map[object_type][reinterpret_cast<uint64_t>(object)] = pNewObjNode;
+    pNewObjNode->status = custom_allocator ? OBJSTATUS_CUSTOM_ALLOCATOR : OBJSTATUS_NONE;
+    pNewObjNode->handle = object_handle;
+    instance_data->object_map[object_type][object_handle] = pNewObjNode;
     instance_data->num_objects[object_type]++;
     instance_data->num_total_objects++;
 }
 
 template <typename T1, typename T2>
-static void CreateNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
+static void DestroyObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type, const VkAllocationCallbacks *pAllocator) {
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
 
-    log_msg(device_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, object_type, reinterpret_cast<uint64_t &>(object),
-            __LINE__, OBJTRACK_NONE, LayerName, "OBJ[0x%" PRIxLEAST64 "] : CREATE %s object 0x%" PRIxLEAST64, object_track_index++,
-            object_name[object_type], reinterpret_cast<uint64_t &>(object));
-
-    OBJTRACK_NODE *pNewObjNode = new OBJTRACK_NODE;
-    pNewObjNode->object_type = object_type;
-    pNewObjNode->status = OBJSTATUS_NONE;
-    pNewObjNode->handle = reinterpret_cast<uint64_t &>(object);
-    device_data->object_map[object_type][reinterpret_cast<uint64_t &>(object)] = pNewObjNode;
-    device_data->num_objects[object_type]++;
-    device_data->num_total_objects++;
-}
-
-template <typename T1, typename T2>
-static void DestroyDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
-    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
-
-    uint64_t object_handle = reinterpret_cast<uint64_t>(object);
-
-    auto item = instance_data->object_map[object_type].find(object_handle);
-    if (item != instance_data->object_map[object_type].end()) {
-
-        OBJTRACK_NODE *pNode = item->second;
-        assert(instance_data->num_total_objects > 0);
-        instance_data->num_total_objects--;
-        assert(instance_data->num_objects[object_type] > 0);
-        instance_data->num_objects[pNode->object_type]--;
-
-        log_msg(instance_data->report_data, VK_DEBUG_REPORT_INFORMATION_BIT_EXT, pNode->object_type, object_handle, __LINE__,
-                OBJTRACK_NONE, LayerName,
-                "OBJ_STAT Destroy %s obj 0x%" PRIxLEAST64 " (%" PRIu64 " total objs remain & %" PRIu64 " %s objs).",
-                object_name[pNode->object_type], reinterpret_cast<uint64_t>(object), instance_data->num_total_objects,
-                instance_data->num_objects[pNode->object_type], object_name[pNode->object_type]);
-
-        delete pNode;
-        instance_data->object_map[object_type].erase(item);
-    } else {
-        log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, (VkDebugReportObjectTypeEXT)0, object_handle, __LINE__,
-                OBJTRACK_UNKNOWN_OBJECT, LayerName,
-                "Unable to remove %s obj 0x%" PRIxLEAST64 ". Was it created? Has it already been destroyed?",
-                object_name[object_type], object_handle);
-    }
-}
-
-template <typename T1, typename T2>
-static void DestroyNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type) {
-    layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
-
-    uint64_t object_handle = reinterpret_cast<uint64_t &>(object);
+    auto object_handle = handle_value(object);
+    bool custom_allocator = pAllocator != nullptr;
 
     auto item = device_data->object_map[object_type].find(object_handle);
     if (item != device_data->object_map[object_type].end()) {
@@ -328,6 +295,15 @@
                 object_name[pNode->object_type], reinterpret_cast<uint64_t &>(object), device_data->num_total_objects,
                 device_data->num_objects[pNode->object_type], object_name[pNode->object_type]);
 
+        auto allocated_with_custom = (pNode->status & OBJSTATUS_CUSTOM_ALLOCATOR) ? true : false;
+        if (custom_allocator ^ allocated_with_custom) {
+            log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle, __LINE__,
+                    OBJTRACK_ALLOCATOR_MISMATCH, LayerName,
+                    "Custom allocator %sspecified while destroying %s obj 0x%" PRIxLEAST64 " but %sspecified at creation",
+                    (custom_allocator ? "" : "not "), object_name[object_type], object_handle,
+                    (allocated_with_custom ? "" : "not "));
+        }
+
         delete pNode;
         device_data->object_map[object_type].erase(item);
     } else {
@@ -339,37 +315,22 @@
 }
 
 template <typename T1, typename T2>
-static bool ValidateDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type,
-                                       bool null_allowed) {
+static bool ValidateObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type, bool null_allowed,
+                           int error_code = -1) {
     if (null_allowed && (object == VK_NULL_HANDLE)) {
         return false;
     }
-    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
+    auto object_handle = handle_value(object);
 
-    if (instance_data->object_map[object_type].find(reinterpret_cast<uint64_t>(object)) ==
-        instance_data->object_map[object_type].end()) {
-        return log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, reinterpret_cast<uint64_t>(object),
-                       __LINE__, OBJTRACK_INVALID_OBJECT, LayerName, "Invalid %s Object 0x%" PRIxLEAST64, object_name[object_type],
-                       reinterpret_cast<uint64_t>(object));
-    }
-    return false;
-}
-
-template <typename T1, typename T2>
-static bool ValidateNonDispatchableObject(T1 dispatchable_object, T2 object, VkDebugReportObjectTypeEXT object_type,
-                                          bool null_allowed) {
-    if (null_allowed && (object == VK_NULL_HANDLE)) {
-        return false;
-    }
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(dispatchable_object), layer_data_map);
-    if (device_data->object_map[object_type].find(reinterpret_cast<uint64_t &>(object)) ==
-        device_data->object_map[object_type].end()) {
+    if (device_data->object_map[object_type].find(object_handle) == device_data->object_map[object_type].end()) {
         // If object is an image, also look for it in the swapchain image map
         if ((object_type != VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT) ||
-            (device_data->swapchainImageMap.find(reinterpret_cast<uint64_t &>(object)) == device_data->swapchainImageMap.end())) {
-            return log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type,
-                           reinterpret_cast<uint64_t &>(object), __LINE__, OBJTRACK_INVALID_OBJECT, LayerName,
-                           "Invalid %s Object 0x%" PRIxLEAST64, object_name[object_type], reinterpret_cast<uint64_t &>(object));
+            (device_data->swapchainImageMap.find(object_handle) == device_data->swapchainImageMap.end())) {
+            const char *error_msg = (error_code == -1) ? "" : validation_error_map[error_code];
+            return log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, object_type, object_handle, __LINE__,
+                           error_code, LayerName, "Invalid %s Object 0x%" PRIxLEAST64 ". %s", object_name[object_type],
+                           object_handle, error_msg);
         }
     }
     return false;
@@ -402,9 +363,9 @@
         }
     }
 
-    ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, true, VALIDATION_ERROR_00021);
 
-    DestroyDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+    DestroyObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pAllocator);
     // Report any remaining objects in LL
 
     for (auto iit = instance_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT].begin();
@@ -473,8 +434,8 @@
 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
 
     std::unique_lock<std::mutex> lock(global_lock);
-    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    DestroyDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+    ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, true, VALIDATION_ERROR_00052);
+    DestroyObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, pAllocator);
 
     // Report any remaining objects associated with this VkDevice object in LL
     DeviceReportUndestroyedObjects(device, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
@@ -516,8 +477,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_01679);
     }
     if (skip_call) {
         return;
@@ -530,8 +491,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_01683);
     }
     if (skip_call) {
         return;
@@ -547,8 +508,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_01686);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -563,8 +524,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_00026);
     }
     if (skip_call) {
         return;
@@ -577,8 +538,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_00609);
     }
     if (skip_call) {
         return;
@@ -602,31 +563,31 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(queue, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true);
+        skip_call |= ValidateObject(queue, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true, VALIDATION_ERROR_00130);
         if (pSubmits) {
             for (uint32_t idx0 = 0; idx0 < submitCount; ++idx0) {
                 if (pSubmits[idx0].pCommandBuffers) {
                     for (uint32_t idx1 = 0; idx1 < pSubmits[idx0].commandBufferCount; ++idx1) {
-                        skip_call |= ValidateDispatchableObject(queue, pSubmits[idx0].pCommandBuffers[idx1],
-                                                                VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+                        skip_call |= ValidateObject(queue, pSubmits[idx0].pCommandBuffers[idx1],
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false, VALIDATION_ERROR_00149);
                     }
                 }
                 if (pSubmits[idx0].pSignalSemaphores) {
                     for (uint32_t idx2 = 0; idx2 < pSubmits[idx0].signalSemaphoreCount; ++idx2) {
-                        skip_call |= ValidateNonDispatchableObject(queue, pSubmits[idx0].pSignalSemaphores[idx2],
-                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+                        skip_call |= ValidateObject(queue, pSubmits[idx0].pSignalSemaphores[idx2],
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false, VALIDATION_ERROR_00150);
                     }
                 }
                 if (pSubmits[idx0].pWaitSemaphores) {
                     for (uint32_t idx3 = 0; idx3 < pSubmits[idx0].waitSemaphoreCount; ++idx3) {
-                        skip_call |= ValidateNonDispatchableObject(queue, pSubmits[idx0].pWaitSemaphores[idx3],
-                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+                        skip_call |= ValidateObject(queue, pSubmits[idx0].pWaitSemaphores[idx3],
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false, VALIDATION_ERROR_00146);
                     }
                 }
             }
         }
         if (queue) {
-            skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+            skip_call |= ValidateObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false, VALIDATION_ERROR_00128);
         }
     }
     if (skip_call) {
@@ -640,7 +601,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+        skip_call |= ValidateObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false, VALIDATION_ERROR_00317);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -653,7 +614,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00318);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -667,7 +628,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00612);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -676,7 +637,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pMemory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+            CreateObject(device, *pMemory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, pAllocator);
         }
     }
     return result;
@@ -687,12 +648,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00635);
         if (pMemoryRanges) {
             for (uint32_t idx0 = 0; idx0 < memoryRangeCount; ++idx0) {
                 if (pMemoryRanges[idx0].memory) {
-                    skip_call |= ValidateNonDispatchableObject(device, pMemoryRanges[idx0].memory,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+                    skip_call |= ValidateObject(device, pMemoryRanges[idx0].memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                                                false, VALIDATION_ERROR_00648);
                 }
             }
         }
@@ -710,12 +671,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00638);
         if (pMemoryRanges) {
             for (uint32_t idx0 = 0; idx0 < memoryRangeCount; ++idx0) {
                 if (pMemoryRanges[idx0].memory) {
-                    skip_call |= ValidateNonDispatchableObject(device, pMemoryRanges[idx0].memory,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+                    skip_call |= ValidateObject(device, pMemoryRanges[idx0].memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT,
+                                                false, VALIDATION_ERROR_00648);
                 }
             }
         }
@@ -733,8 +694,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00654);
+        skip_call |= ValidateObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false, VALIDATION_ERROR_00655);
     }
     if (skip_call) {
         return;
@@ -747,9 +708,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+        skip_call |= ValidateObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00799);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00798);
+        skip_call |= ValidateObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false, VALIDATION_ERROR_00800);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -762,9 +723,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00807);
+        skip_call |= ValidateObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00808);
+        skip_call |= ValidateObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false, VALIDATION_ERROR_00809);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -778,8 +739,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00784);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00783);
     }
     if (skip_call) {
         return;
@@ -791,8 +752,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00787);
+        skip_call |= ValidateObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00788);
     }
     if (skip_call) {
         return;
@@ -805,8 +766,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_01610);
+        skip_call |= ValidateObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01611);
     }
     if (skip_call) {
         return;
@@ -823,8 +784,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false,
+                                    VALIDATION_ERROR_01601);
     }
     if (skip_call) {
         return;
@@ -839,7 +800,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00166);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -848,7 +809,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pFence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+            CreateObject(device, *pFence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, pAllocator);
         }
     }
     return result;
@@ -858,15 +819,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00176);
+        skip_call |= ValidateObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true, VALIDATION_ERROR_00177);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT);
+        DestroyObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyFence(device, fence, pAllocator);
 }
@@ -875,10 +836,11 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00184);
         if (pFences) {
             for (uint32_t idx0 = 0; idx0 < fenceCount; ++idx0) {
-                skip_call |= ValidateNonDispatchableObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+                skip_call |=
+                    ValidateObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false, VALIDATION_ERROR_00187);
             }
         }
     }
@@ -893,8 +855,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00180);
+        skip_call |= ValidateObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false, VALIDATION_ERROR_00181);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -908,10 +870,11 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00188);
         if (pFences) {
             for (uint32_t idx0 = 0; idx0 < fenceCount; ++idx0) {
-                skip_call |= ValidateNonDispatchableObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false);
+                skip_call |=
+                    ValidateObject(device, pFences[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, false, VALIDATION_ERROR_00191);
             }
         }
     }
@@ -927,7 +890,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00192);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -936,7 +899,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pSemaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+            CreateObject(device, *pSemaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, pAllocator);
         }
     }
     return result;
@@ -946,15 +909,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00202);
+        skip_call |= ValidateObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, true, VALIDATION_ERROR_00203);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT);
+        DestroyObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroySemaphore(device, semaphore, pAllocator);
 }
@@ -964,7 +927,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00206);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -973,7 +936,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pEvent, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+            CreateObject(device, *pEvent, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, pAllocator);
         }
     }
     return result;
@@ -983,15 +946,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00216);
+        skip_call |= ValidateObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, true, VALIDATION_ERROR_00217);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT);
+        DestroyObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyEvent(device, event, pAllocator);
 }
@@ -1000,8 +963,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00220);
+        skip_call |= ValidateObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false, VALIDATION_ERROR_00221);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1014,8 +977,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00223);
+        skip_call |= ValidateObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false, VALIDATION_ERROR_00224);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1028,8 +991,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00227);
+        skip_call |= ValidateObject(device, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false, VALIDATION_ERROR_00228);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1043,7 +1006,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_01002);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1052,7 +1015,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pQueryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+            CreateObject(device, *pQueryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, pAllocator);
         }
     }
     return result;
@@ -1062,15 +1025,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_01015);
+        skip_call |= ValidateObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, true, VALIDATION_ERROR_01016);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT);
+        DestroyObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyQueryPool(device, queryPool, pAllocator);
 }
@@ -1080,8 +1043,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_01054);
+        skip_call |= ValidateObject(device, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01055);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1096,7 +1059,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00659);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1105,7 +1068,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+            CreateObject(device, *pBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, pAllocator);
         }
     }
     return result;
@@ -1115,15 +1078,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, true, VALIDATION_ERROR_00680);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00679);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT);
+        DestroyObject(device, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyBuffer(device, buffer, pAllocator);
 }
@@ -1133,9 +1096,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00683);
         if (pCreateInfo) {
-            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            skip_call |=
+                ValidateObject(device, pCreateInfo->buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00699);
         }
     }
     if (skip_call) {
@@ -1145,7 +1109,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+            CreateObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, pAllocator);
         }
     }
     return result;
@@ -1155,15 +1119,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, true, VALIDATION_ERROR_00705);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00704);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT);
+        DestroyObject(device, bufferView, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyBufferView(device, bufferView, pAllocator);
 }
@@ -1173,7 +1137,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00709);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1182,7 +1146,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+            CreateObject(device, *pImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, pAllocator);
         }
     }
     return result;
@@ -1192,15 +1156,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00746);
+        skip_call |= ValidateObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, true, VALIDATION_ERROR_00747);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT);
+        DestroyObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyImage(device, image, pAllocator);
 }
@@ -1210,8 +1174,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00734);
+        skip_call |= ValidateObject(device, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00735);
     }
     if (skip_call) {
         return;
@@ -1224,9 +1188,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00750);
         if (pCreateInfo) {
-            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+            skip_call |=
+                ValidateObject(device, pCreateInfo->image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00763);
         }
     }
     if (skip_call) {
@@ -1236,7 +1201,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+            CreateObject(device, *pView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, pAllocator);
         }
     }
     return result;
@@ -1246,15 +1211,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00779);
+        skip_call |= ValidateObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, true, VALIDATION_ERROR_00780);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT);
+        DestroyObject(device, imageView, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyImageView(device, imageView, pAllocator);
 }
@@ -1264,7 +1229,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00466);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1274,7 +1239,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pShaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+            CreateObject(device, *pShaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, pAllocator);
         }
     }
     return result;
@@ -1285,15 +1250,16 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00481);
+        skip_call |=
+            ValidateObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, true, VALIDATION_ERROR_00482);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT);
+        DestroyObject(device, shaderModule, VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyShaderModule(device, shaderModule, pAllocator);
 }
@@ -1303,7 +1269,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00562);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1313,7 +1279,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pPipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+            CreateObject(device, *pPipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, pAllocator);
         }
     }
     return result;
@@ -1324,15 +1290,16 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00585);
+        skip_call |=
+            ValidateObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, true, VALIDATION_ERROR_00586);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT);
+        DestroyObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyPipelineCache(device, pipelineCache, pAllocator);
 }
@@ -1342,8 +1309,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00578);
+        skip_call |=
+            ValidateObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false, VALIDATION_ERROR_00579);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1358,12 +1326,13 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, dstCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00572);
+        skip_call |=
+            ValidateObject(device, dstCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false, VALIDATION_ERROR_00573);
         if (pSrcCaches) {
             for (uint32_t idx0 = 0; idx0 < srcCacheCount; ++idx0) {
-                skip_call |=
-                    ValidateNonDispatchableObject(device, pSrcCaches[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+                skip_call |= ValidateObject(device, pSrcCaches[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false,
+                                            VALIDATION_ERROR_00577);
             }
         }
     }
@@ -1379,15 +1348,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00558);
+        skip_call |= ValidateObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true, VALIDATION_ERROR_00559);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+        DestroyObject(device, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyPipeline(device, pipeline, pAllocator);
 }
@@ -1397,12 +1366,13 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00861);
         if (pCreateInfo) {
             if (pCreateInfo->pSetLayouts) {
                 for (uint32_t idx0 = 0; idx0 < pCreateInfo->setLayoutCount; ++idx0) {
-                    skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->pSetLayouts[idx0],
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
+                    skip_call |=
+                        ValidateObject(device, pCreateInfo->pSetLayouts[idx0],
+                                       VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false, VALIDATION_ERROR_00875);
                 }
             }
         }
@@ -1415,7 +1385,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pPipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+            CreateObject(device, *pPipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, pAllocator);
         }
     }
     return result;
@@ -1426,15 +1396,16 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00885);
+        skip_call |=
+            ValidateObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, true, VALIDATION_ERROR_00886);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT);
+        DestroyObject(device, pipelineLayout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyPipelineLayout(device, pipelineLayout, pAllocator);
 }
@@ -1444,7 +1415,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00812);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1453,7 +1424,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pSampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+            CreateObject(device, *pSampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, pAllocator);
         }
     }
     return result;
@@ -1463,15 +1434,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00840);
+        skip_call |= ValidateObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, true, VALIDATION_ERROR_00841);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT);
+        DestroyObject(device, sampler, VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroySampler(device, sampler, pAllocator);
 }
@@ -1482,15 +1453,17 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00844);
         if (pCreateInfo) {
             if (pCreateInfo->pBindings) {
                 for (uint32_t idx0 = 0; idx0 < pCreateInfo->bindingCount; ++idx0) {
-                    if (pCreateInfo->pBindings[idx0].pImmutableSamplers) {
-                        for (uint32_t idx1 = 0; idx1 < pCreateInfo->pBindings[idx0].descriptorCount; ++idx1) {
-                            skip_call |=
-                                ValidateNonDispatchableObject(device, pCreateInfo->pBindings[idx0].pImmutableSamplers[idx1],
-                                                              VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
+                    if ((pCreateInfo->pBindings[idx0].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
+                        (pCreateInfo->pBindings[idx0].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)) {
+                        if (pCreateInfo->pBindings[idx0].pImmutableSamplers) {
+                            for (uint32_t idx1 = 0; idx1 < pCreateInfo->pBindings[idx0].descriptorCount; ++idx1) {
+                                skip_call |= ValidateObject(device, pCreateInfo->pBindings[idx0].pImmutableSamplers[idx1],
+                                                            VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false, VALIDATION_ERROR_00852);
+                            }
                         }
                     }
                 }
@@ -1505,7 +1478,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+            CreateObject(device, *pSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, pAllocator);
         }
     }
     return result;
@@ -1516,16 +1489,16 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, descriptorSetLayout,
-                                                   VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, descriptorSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, true,
+                                    VALIDATION_ERROR_00858);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00857);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, descriptorSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT);
+        DestroyObject(device, descriptorSetLayout, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyDescriptorSetLayout(device, descriptorSetLayout, pAllocator);
 }
@@ -1535,7 +1508,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00889);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1545,7 +1518,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pDescriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+            CreateObject(device, *pDescriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, pAllocator);
         }
     }
     return result;
@@ -1554,14 +1527,26 @@
 VKAPI_ATTR VkResult VKAPI_CALL ResetDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool,
                                                    VkDescriptorPoolResetFlags flags) {
     bool skip_call = false;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    }
+    std::unique_lock<std::mutex> lock(global_lock);
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    skip_call |=
+        ValidateObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false, VALIDATION_ERROR_00930);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00929);
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
     }
+    // A DescriptorPool's descriptor sets are implicitly deleted when the pool is reset.
+    // Remove this pool's descriptor sets from our descriptorSet map.
+    auto itr = device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].begin();
+    while (itr != device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT].end()) {
+        OBJTRACK_NODE *pNode = (*itr).second;
+        auto del_itr = itr++;
+        if (pNode->parent_object == reinterpret_cast<uint64_t &>(descriptorPool)) {
+            DestroyObject(device, (VkDescriptorSet)((*del_itr).first),
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, nullptr);
+        }
+    }
+    lock.unlock();
     VkResult result = get_dispatch_table(ot_device_table_map, device)->ResetDescriptorPool(device, descriptorPool, flags);
     return result;
 }
@@ -1572,57 +1557,52 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00933);
         if (pDescriptorCopies) {
             for (uint32_t idx0 = 0; idx0 < descriptorCopyCount; ++idx0) {
                 if (pDescriptorCopies[idx0].dstSet) {
-                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorCopies[idx0].dstSet,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                    skip_call |= ValidateObject(device, pDescriptorCopies[idx0].dstSet,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false, VALIDATION_ERROR_00972);
                 }
                 if (pDescriptorCopies[idx0].srcSet) {
-                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorCopies[idx0].srcSet,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                    skip_call |= ValidateObject(device, pDescriptorCopies[idx0].srcSet,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false, VALIDATION_ERROR_00971);
                 }
             }
         }
         if (pDescriptorWrites) {
             for (uint32_t idx1 = 0; idx1 < descriptorWriteCount; ++idx1) {
                 if (pDescriptorWrites[idx1].dstSet) {
-                    skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].dstSet,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
+                    skip_call |= ValidateObject(device, pDescriptorWrites[idx1].dstSet,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false, VALIDATION_ERROR_00955);
+                }
+                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
+                    for (uint32_t idx2 = 0; idx2 < pDescriptorWrites[idx1].descriptorCount; ++idx2) {
+                        skip_call |= ValidateObject(device, pDescriptorWrites[idx1].pTexelBufferView[idx2],
+                                                    VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, false, VALIDATION_ERROR_00940);
+                    }
+                }
+                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
+                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT)) {
+                    for (uint32_t idx3 = 0; idx3 < pDescriptorWrites[idx1].descriptorCount; ++idx3) {
+                        if (pDescriptorWrites[idx1].pImageInfo[idx3].imageView) {
+                            skip_call |= ValidateObject(device, pDescriptorWrites[idx1].pImageInfo[idx3].imageView,
+                                                        VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false, VALIDATION_ERROR_00943);
+                        }
+                    }
                 }
                 if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) ||
                     (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) ||
                     (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) ||
                     (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC)) {
-                    for (uint32_t idx2 = 0; idx2 < pDescriptorWrites[idx1].descriptorCount; ++idx2) {
-                        if (pDescriptorWrites[idx1].pBufferInfo[idx2].buffer) {
-                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pBufferInfo[idx2].buffer,
-                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-                        }
-                    }
-                }
-                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER) ||
-                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) ||
-                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT) ||
-                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
-                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)) {
-                    for (uint32_t idx3 = 0; idx3 < pDescriptorWrites[idx1].descriptorCount; ++idx3) {
-                        if (pDescriptorWrites[idx1].pImageInfo[idx3].imageView) {
-                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pImageInfo[idx3].imageView,
-                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
-                        }
-                        if (pDescriptorWrites[idx1].pImageInfo[idx3].sampler) {
-                            skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pImageInfo[idx3].sampler,
-                                                                       VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT, false);
-                        }
-                    }
-                }
-                if ((pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) ||
-                    (pDescriptorWrites[idx1].descriptorType == VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)) {
                     for (uint32_t idx4 = 0; idx4 < pDescriptorWrites[idx1].descriptorCount; ++idx4) {
-                        skip_call |= ValidateNonDispatchableObject(device, pDescriptorWrites[idx1].pTexelBufferView[idx4],
-                                                                   VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT, true);
+                        if (pDescriptorWrites[idx1].pBufferInfo[idx4].buffer) {
+                            skip_call |= ValidateObject(device, pDescriptorWrites[idx1].pBufferInfo[idx4].buffer,
+                                                        VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00962);
+                        }
                     }
                 }
             }
@@ -1640,17 +1620,17 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00400);
         if (pCreateInfo) {
             if (pCreateInfo->pAttachments) {
                 for (uint32_t idx0 = 0; idx0 < pCreateInfo->attachmentCount; ++idx0) {
-                    skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->pAttachments[idx0],
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT, false);
+                    skip_call |= ValidateObject(device, pCreateInfo->pAttachments[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT,
+                                                false, VALIDATION_ERROR_00420);
                 }
             }
             if (pCreateInfo->renderPass) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->renderPass,
-                                                           VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+                skip_call |= ValidateObject(device, pCreateInfo->renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false,
+                                            VALIDATION_ERROR_00419);
             }
         }
     }
@@ -1662,7 +1642,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pFramebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+            CreateObject(device, *pFramebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, pAllocator);
         }
     }
     return result;
@@ -1672,15 +1652,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00425);
+        skip_call |= ValidateObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, true, VALIDATION_ERROR_00426);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT);
+        DestroyObject(device, framebuffer, VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyFramebuffer(device, framebuffer, pAllocator);
 }
@@ -1690,7 +1670,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00319);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1700,7 +1680,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pRenderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+            CreateObject(device, *pRenderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, pAllocator);
         }
     }
     return result;
@@ -1710,15 +1690,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00396);
+        skip_call |= ValidateObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, true, VALIDATION_ERROR_00397);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT);
+        DestroyObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, pAllocator);
     }
     get_dispatch_table(ot_device_table_map, device)->DestroyRenderPass(device, renderPass, pAllocator);
 }
@@ -1727,8 +1707,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00449);
+        skip_call |= ValidateObject(device, renderPass, VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false, VALIDATION_ERROR_00450);
     }
     if (skip_call) {
         return;
@@ -1741,7 +1721,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00064);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1751,7 +1731,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pCommandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+            CreateObject(device, *pCommandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, pAllocator);
         }
     }
     return result;
@@ -1761,8 +1741,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |=
+            ValidateObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false, VALIDATION_ERROR_00074);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00073);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1776,15 +1757,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(command_buffer, command_buffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(command_buffer, command_buffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00108);
         if (begin_info) {
             OBJTRACK_NODE *pNode =
                 device_data->object_map[VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT][reinterpret_cast<const uint64_t>(command_buffer)];
             if ((begin_info->pInheritanceInfo) && (pNode->status & OBJSTATUS_COMMAND_BUFFER_SECONDARY)) {
-                skip_call |= ValidateNonDispatchableObject(command_buffer, begin_info->pInheritanceInfo->framebuffer,
+                skip_call |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->framebuffer,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, true);
-                skip_call |= ValidateNonDispatchableObject(command_buffer, begin_info->pInheritanceInfo->renderPass,
+                skip_call |= ValidateObject(command_buffer, begin_info->pInheritanceInfo->renderPass,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, true);
             }
         }
@@ -1800,8 +1781,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00125);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1814,8 +1795,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00090);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -1829,9 +1810,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00599);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, false);
+            ValidateObject(commandBuffer, pipeline, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, false, VALIDATION_ERROR_00601);
     }
     if (skip_call) {
         return;
@@ -1844,8 +1826,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01443);
     }
     if (skip_call) {
         return;
@@ -1858,8 +1840,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01492);
     }
     if (skip_call) {
         return;
@@ -1871,8 +1853,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01478);
     }
     if (skip_call) {
         return;
@@ -1885,8 +1867,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01483);
     }
     if (skip_call) {
         return;
@@ -1899,8 +1881,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01551);
     }
     if (skip_call) {
         return;
@@ -1912,8 +1894,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01507);
     }
     if (skip_call) {
         return;
@@ -1926,8 +1908,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01515);
     }
     if (skip_call) {
         return;
@@ -1939,8 +1921,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01521);
     }
     if (skip_call) {
         return;
@@ -1952,8 +1934,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01527);
     }
     if (skip_call) {
         return;
@@ -1968,12 +1950,13 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00979);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+            ValidateObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false, VALIDATION_ERROR_00981);
         if (pDescriptorSets) {
             for (uint32_t idx0 = 0; idx0 < descriptorSetCount; ++idx0) {
-                skip_call |= ValidateNonDispatchableObject(commandBuffer, pDescriptorSets[idx0],
+                skip_call |= ValidateObject(commandBuffer, pDescriptorSets[idx0],
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, false);
             }
         }
@@ -1991,9 +1974,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01354);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01353);
     }
     if (skip_call) {
         return;
@@ -2006,12 +1989,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01419);
         if (pBuffers) {
             for (uint32_t idx0 = 0; idx0 < bindingCount; ++idx0) {
                 skip_call |=
-                    ValidateNonDispatchableObject(commandBuffer, pBuffers[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                    ValidateObject(commandBuffer, pBuffers[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
             }
         }
     }
@@ -2027,8 +2010,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01362);
     }
     if (skip_call) {
         return;
@@ -2042,8 +2025,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01369);
     }
     if (skip_call) {
         return;
@@ -2057,9 +2040,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01378);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01377);
     }
     if (skip_call) {
         return;
@@ -2072,9 +2055,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01390);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01389);
     }
     if (skip_call) {
         return;
@@ -2087,8 +2070,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01559);
     }
     if (skip_call) {
         return;
@@ -2100,9 +2083,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01566);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01565);
     }
     if (skip_call) {
         return;
@@ -2115,10 +2098,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01166);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            ValidateObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01168);
+        skip_call |=
+            ValidateObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01167);
     }
     if (skip_call) {
         return;
@@ -2133,10 +2118,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01186);
+        skip_call |= ValidateObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01189);
+        skip_call |= ValidateObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01187);
     }
     if (skip_call) {
         return;
@@ -2151,10 +2136,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01291);
+        skip_call |= ValidateObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01294);
+        skip_call |= ValidateObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01292);
     }
     if (skip_call) {
         return;
@@ -2169,10 +2154,11 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01235);
+        skip_call |= ValidateObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01237);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            ValidateObject(commandBuffer, srcBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01236);
     }
     if (skip_call) {
         return;
@@ -2186,10 +2172,11 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01253);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+            ValidateObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01256);
+        skip_call |= ValidateObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01254);
     }
     if (skip_call) {
         return;
@@ -2203,9 +2190,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01150);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            ValidateObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01151);
     }
     if (skip_call) {
         return;
@@ -2218,9 +2206,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01138);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+            ValidateObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01139);
     }
     if (skip_call) {
         return;
@@ -2234,9 +2223,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01089);
+        skip_call |= ValidateObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01090);
     }
     if (skip_call) {
         return;
@@ -2251,9 +2240,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01104);
+        skip_call |= ValidateObject(commandBuffer, image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01105);
     }
     if (skip_call) {
         return;
@@ -2268,8 +2257,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01117);
     }
     if (skip_call) {
         return;
@@ -2284,10 +2273,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01327);
+        skip_call |= ValidateObject(commandBuffer, dstImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01330);
+        skip_call |= ValidateObject(commandBuffer, srcImage, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_01328);
     }
     if (skip_call) {
         return;
@@ -2300,9 +2289,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00232);
+        skip_call |= ValidateObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false, VALIDATION_ERROR_00233);
     }
     if (skip_call) {
         return;
@@ -2314,9 +2303,9 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00243);
+        skip_call |= ValidateObject(commandBuffer, event, VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false, VALIDATION_ERROR_00244);
     }
     if (skip_call) {
         return;
@@ -2332,27 +2321,27 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00252);
         if (pBufferMemoryBarriers) {
             for (uint32_t idx0 = 0; idx0 < bufferMemoryBarrierCount; ++idx0) {
                 if (pBufferMemoryBarriers[idx0].buffer) {
-                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                    skip_call |= ValidateObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00259);
                 }
             }
         }
         if (pEvents) {
             for (uint32_t idx1 = 0; idx1 < eventCount; ++idx1) {
-                skip_call |=
-                    ValidateNonDispatchableObject(commandBuffer, pEvents[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false);
+                skip_call |= ValidateObject(commandBuffer, pEvents[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT, false,
+                                            VALIDATION_ERROR_00253);
             }
         }
         if (pImageMemoryBarriers) {
             for (uint32_t idx2 = 0; idx2 < imageMemoryBarrierCount; ++idx2) {
                 if (pImageMemoryBarriers[idx2].image) {
-                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pImageMemoryBarriers[idx2].image,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+                    skip_call |= ValidateObject(commandBuffer, pImageMemoryBarriers[idx2].image,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00260);
                 }
             }
         }
@@ -2373,21 +2362,21 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00270);
         if (pBufferMemoryBarriers) {
             for (uint32_t idx0 = 0; idx0 < bufferMemoryBarrierCount; ++idx0) {
                 if (pBufferMemoryBarriers[idx0].buffer) {
-                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+                    skip_call |= ValidateObject(commandBuffer, pBufferMemoryBarriers[idx0].buffer,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_00277);
                 }
             }
         }
         if (pImageMemoryBarriers) {
             for (uint32_t idx1 = 0; idx1 < imageMemoryBarrierCount; ++idx1) {
                 if (pImageMemoryBarriers[idx1].image) {
-                    skip_call |= ValidateNonDispatchableObject(commandBuffer, pImageMemoryBarriers[idx1].image,
-                                                               VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+                    skip_call |= ValidateObject(commandBuffer, pImageMemoryBarriers[idx1].image,
+                                                VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false, VALIDATION_ERROR_00278);
                 }
             }
         }
@@ -2405,9 +2394,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01035);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+            ValidateObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01036);
     }
     if (skip_call) {
         return;
@@ -2419,9 +2409,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01043);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+            ValidateObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01044);
     }
     if (skip_call) {
         return;
@@ -2434,9 +2425,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01021);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+            ValidateObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01022);
     }
     if (skip_call) {
         return;
@@ -2449,9 +2441,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01078);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+            ValidateObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01080);
     }
     if (skip_call) {
         return;
@@ -2465,10 +2458,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_01068);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false);
+            ValidateObject(commandBuffer, dstBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false, VALIDATION_ERROR_01070);
+        skip_call |=
+            ValidateObject(commandBuffer, queryPool, VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT, false, VALIDATION_ERROR_01069);
     }
     if (skip_call) {
         return;
@@ -2482,9 +2477,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00993);
         skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
+            ValidateObject(commandBuffer, layout, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false, VALIDATION_ERROR_00994);
     }
     if (skip_call) {
         return;
@@ -2498,12 +2494,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00435);
         if (pRenderPassBegin) {
-            skip_call |= ValidateNonDispatchableObject(commandBuffer, pRenderPassBegin->framebuffer,
+            skip_call |= ValidateObject(commandBuffer, pRenderPassBegin->framebuffer,
                                                        VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT, false);
-            skip_call |= ValidateNonDispatchableObject(commandBuffer, pRenderPassBegin->renderPass,
+            skip_call |= ValidateObject(commandBuffer, pRenderPassBegin->renderPass,
                                                        VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
         }
     }
@@ -2517,8 +2513,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00454);
     }
     if (skip_call) {
         return;
@@ -2530,8 +2526,8 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00461);
     }
     if (skip_call) {
         return;
@@ -2544,12 +2540,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |=
-            ValidateDispatchableObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+        skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false,
+                                    VALIDATION_ERROR_00159);
         if (pCommandBuffers) {
             for (uint32_t idx0 = 0; idx0 < commandBufferCount; ++idx0) {
-                skip_call |= ValidateDispatchableObject(commandBuffer, pCommandBuffers[idx0],
-                                                        VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+                skip_call |= ValidateObject(commandBuffer, pCommandBuffers[idx0], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT,
+                                            false, VALIDATION_ERROR_00160);
             }
         }
     }
@@ -2563,15 +2559,15 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
     }
     if (skip_call) {
         return;
     }
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        DestroyNonDispatchableObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+        DestroyObject(instance, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
     }
     get_dispatch_table(ot_instance_table_map, instance)->DestroySurfaceKHR(instance, surface, pAllocator);
 }
@@ -2582,8 +2578,8 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2599,8 +2595,8 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2617,8 +2613,8 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2635,8 +2631,8 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+        skip_call |= ValidateObject(physicalDevice, surface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2651,12 +2647,12 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
         if (pCreateInfo) {
-            skip_call |= ValidateNonDispatchableObject(device, pCreateInfo->oldSwapchain,
+            skip_call |= ValidateObject(device, pCreateInfo->oldSwapchain,
                                                        VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, true);
             layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-            skip_call |= ValidateNonDispatchableObject(device_data->physical_device, pCreateInfo->surface,
+            skip_call |= ValidateObject(device_data->physical_device, pCreateInfo->surface,
                                                        VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
         }
     }
@@ -2668,7 +2664,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(device, *pSwapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+            CreateObject(device, *pSwapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2679,10 +2675,10 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-        skip_call |= ValidateNonDispatchableObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true);
-        skip_call |= ValidateNonDispatchableObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, true);
-        skip_call |= ValidateNonDispatchableObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, fence, VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT, true);
+        skip_call |= ValidateObject(device, semaphore, VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, true);
+        skip_call |= ValidateObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2699,18 +2695,18 @@
         if (pPresentInfo) {
             if (pPresentInfo->pSwapchains) {
                 for (uint32_t idx0 = 0; idx0 < pPresentInfo->swapchainCount; ++idx0) {
-                    skip_call |= ValidateNonDispatchableObject(queue, pPresentInfo->pSwapchains[idx0],
+                    skip_call |= ValidateObject(queue, pPresentInfo->pSwapchains[idx0],
                                                                VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, false);
                 }
             }
             if (pPresentInfo->pWaitSemaphores) {
                 for (uint32_t idx1 = 0; idx1 < pPresentInfo->waitSemaphoreCount; ++idx1) {
-                    skip_call |= ValidateNonDispatchableObject(queue, pPresentInfo->pWaitSemaphores[idx1],
+                    skip_call |= ValidateObject(queue, pPresentInfo->pWaitSemaphores[idx1],
                                                                VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT, false);
                 }
             }
         }
-        skip_call |= ValidateDispatchableObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
+        skip_call |= ValidateObject(queue, queue, VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2725,7 +2721,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2735,7 +2731,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2747,7 +2743,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
     }
     if (skip_call) {
         return VK_FALSE;
@@ -2764,7 +2760,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2774,7 +2770,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2787,7 +2783,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
     }
     if (skip_call) {
         return VK_FALSE;
@@ -2804,7 +2800,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2814,7 +2810,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2827,7 +2823,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
     }
     if (skip_call) {
         return VK_FALSE;
@@ -2844,7 +2840,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2854,7 +2850,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2866,7 +2862,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
     }
     if (skip_call) {
         return VK_FALSE;
@@ -2883,7 +2879,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2893,7 +2889,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2906,7 +2902,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         skip_call |=
-            ValidateDispatchableObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+            ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
     }
     if (skip_call) {
         return VK_FALSE;
@@ -2923,7 +2919,7 @@
     bool skip_call = false;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+        skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
     }
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -2933,7 +2929,7 @@
     {
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
-            CreateNonDispatchableObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT);
+            CreateObject(instance, *pSurface, VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, pAllocator);
         }
     }
     return result;
@@ -2947,13 +2943,13 @@
     uint32_t i = 0;
     {
         std::lock_guard<std::mutex> lock(global_lock);
-        skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+        skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
         if (NULL != pCreateInfos) {
             for (i = 0; i < swapchainCount; i++) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[i].oldSwapchain,
+                skip_call |= ValidateObject(device, pCreateInfos[i].oldSwapchain,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, true);
                 layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-                skip_call |= ValidateNonDispatchableObject(device_data->physical_device, pCreateInfos[i].surface,
+                skip_call |= ValidateObject(device_data->physical_device, pCreateInfos[i].surface,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT, false);
             }
         }
@@ -2967,7 +2963,7 @@
         std::lock_guard<std::mutex> lock(global_lock);
         if (result == VK_SUCCESS) {
             for (i = 0; i < swapchainCount; i++) {
-                CreateNonDispatchableObject(device, pSwapchains[i], VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+                CreateObject(device, pSwapchains[i], VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pAllocator);
             }
         }
     }
@@ -2983,7 +2979,7 @@
     if (VK_SUCCESS == result) {
         layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
         result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pCallback);
-        CreateNonDispatchableObject(instance, *pCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+        CreateObject(instance, *pCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, pAllocator);
     }
     return result;
 }
@@ -2994,7 +2990,7 @@
     pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
     layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
     layer_destroy_msg_callback(instance_data->report_data, msgCallback, pAllocator);
-    DestroyNonDispatchableObject(instance, msgCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT);
+    DestroyObject(instance, msgCallback, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, pAllocator);
 }
 
 VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
@@ -3190,7 +3186,7 @@
     initDeviceTable(*pDevice, fpGetDeviceProcAddr, ot_device_table_map);
 
     CheckDeviceRegisterExtensions(pCreateInfo, *pDevice);
-    CreateDispatchableObject(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT);
+    CreateObject(*pDevice, *pDevice, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, pAllocator);
 
     return result;
 }
@@ -3244,7 +3240,7 @@
     InitObjectTracker(instance_data, pAllocator);
     CheckInstanceRegisterExtensions(pCreateInfo, *pInstance);
 
-    CreateDispatchableObject(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT);
+    CreateObject(*pInstance, *pInstance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, pAllocator);
 
     return result;
 }
@@ -3253,7 +3249,7 @@
                                                         VkPhysicalDevice *pPhysicalDevices) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false);
+    skip_call |= ValidateObject(instance, instance, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT, false, VALIDATION_ERROR_00023);
     lock.unlock();
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -3264,7 +3260,7 @@
     if (result == VK_SUCCESS) {
         if (pPhysicalDevices) {
             for (uint32_t i = 0; i < *pPhysicalDeviceCount; i++) {
-                CreateDispatchableObject(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT);
+                CreateObject(instance, pPhysicalDevices[i], VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, nullptr);
             }
         }
     }
@@ -3274,7 +3270,7 @@
 
 VKAPI_ATTR void VKAPI_CALL GetDeviceQueue(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue *pQueue) {
     std::unique_lock<std::mutex> lock(global_lock);
-    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00062);
     lock.unlock();
 
     get_dispatch_table(ot_device_table_map, device)->GetDeviceQueue(device, queueFamilyIndex, queueIndex, pQueue);
@@ -3286,21 +3282,24 @@
 }
 
 VKAPI_ATTR void VKAPI_CALL FreeMemory(VkDevice device, VkDeviceMemory memory, const VkAllocationCallbacks *pAllocator) {
+    bool skip = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00621);
+    skip |= ValidateObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, true, VALIDATION_ERROR_00622);
     lock.unlock();
+    if (!skip) {
+        get_dispatch_table(ot_device_table_map, device)->FreeMemory(device, memory, pAllocator);
 
-    get_dispatch_table(ot_device_table_map, device)->FreeMemory(device, memory, pAllocator);
-
-    lock.lock();
-    DestroyNonDispatchableObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT);
+        lock.lock();
+        DestroyObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, pAllocator);
+    }
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL MapMemory(VkDevice device, VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size,
                                          VkMemoryMapFlags flags, void **ppData) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00631);
     lock.unlock();
     if (skip_call == VK_TRUE) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -3312,7 +3311,7 @@
 VKAPI_ATTR void VKAPI_CALL UnmapMemory(VkDevice device, VkDeviceMemory memory) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00650);
     lock.unlock();
     if (skip_call == VK_TRUE) {
         return;
@@ -3327,13 +3326,13 @@
 
     for (uint32_t i = 0; i < bindInfoCount; i++) {
         for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; j++)
-            ValidateNonDispatchableObject(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
+            ValidateObject(queue, pBindInfo[i].pBufferBinds[j].buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT,
                                           false);
         for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; j++)
-            ValidateNonDispatchableObject(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
+            ValidateObject(queue, pBindInfo[i].pImageOpaqueBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT,
                                           false);
         for (uint32_t j = 0; j < pBindInfo[i].imageBindCount; j++)
-            ValidateNonDispatchableObject(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
+            ValidateObject(queue, pBindInfo[i].pImageBinds[j].image, VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT, false);
     }
     lock.unlock();
 
@@ -3345,9 +3344,9 @@
                                                       VkCommandBuffer *pCommandBuffers) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skip_call |=
-        ValidateNonDispatchableObject(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00084);
+    skip_call |= ValidateObject(device, pAllocateInfo->commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false,
+                                VALIDATION_ERROR_00090);
     lock.unlock();
 
     if (skip_call) {
@@ -3371,11 +3370,11 @@
                                                       VkDescriptorSet *pDescriptorSets) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skip_call |= ValidateNonDispatchableObject(device, pAllocateInfo->descriptorPool,
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00908);
+    skip_call |= ValidateObject(device, pAllocateInfo->descriptorPool,
                                                VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
     for (uint32_t i = 0; i < pAllocateInfo->descriptorSetCount; i++) {
-        skip_call |= ValidateNonDispatchableObject(device, pAllocateInfo->pSetLayouts[i],
+        skip_call |= ValidateObject(device, pAllocateInfo->pSetLayouts[i],
                                                    VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT, false);
     }
     lock.unlock();
@@ -3402,14 +3401,14 @@
                                               const VkCommandBuffer *pCommandBuffers) {
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
-    ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    ValidateObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false, VALIDATION_ERROR_00099);
+    ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00098);
     for (uint32_t i = 0; i < commandBufferCount; i++) {
         skip_call |= ValidateCommandBuffer(device, commandPool, pCommandBuffers[i]);
     }
 
     for (uint32_t i = 0; i < commandBufferCount; i++) {
-        DestroyDispatchableObject(device, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT);
+        DestroyObject(device, pCommandBuffers[i], VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, nullptr);
     }
 
     lock.unlock();
@@ -3434,7 +3433,7 @@
             ++itr;
         }
     }
-    DestroyNonDispatchableObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT);
+    DestroyObject(device, swapchain, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT, pAllocator);
     lock.unlock();
 
     get_dispatch_table(ot_device_table_map, device)->DestroySwapchainKHR(device, swapchain, pAllocator);
@@ -3445,14 +3444,15 @@
     bool skip_call = false;
     VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |=
+        ValidateObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false, VALIDATION_ERROR_00924);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00923);
     for (uint32_t i = 0; i < descriptorSetCount; i++) {
         skip_call |= ValidateDescriptorSet(device, descriptorPool, pDescriptorSets[i]);
     }
 
     for (uint32_t i = 0; i < descriptorSetCount; i++) {
-        DestroyNonDispatchableObject(device, pDescriptorSets[i], VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+        DestroyObject(device, pDescriptorSets[i], VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, nullptr);
     }
 
     lock.unlock();
@@ -3468,8 +3468,9 @@
     bool skip_call = VK_FALSE;
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skip_call |= ValidateNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00904);
+    skip_call |=
+        ValidateObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, true, VALIDATION_ERROR_00905);
     lock.unlock();
     if (skip_call) {
         return;
@@ -3483,11 +3484,11 @@
         OBJTRACK_NODE *pNode = (*itr).second;
         auto del_itr = itr++;
         if (pNode->parent_object == reinterpret_cast<uint64_t &>(descriptorPool)) {
-            DestroyNonDispatchableObject(device, (VkDescriptorSet)((*del_itr).first),
-                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT);
+            DestroyObject(device, (VkDescriptorSet)((*del_itr).first),
+                                         VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT, nullptr);
         }
     }
-    DestroyNonDispatchableObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT);
+    DestroyObject(device, descriptorPool, VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT, pAllocator);
     lock.unlock();
     get_dispatch_table(ot_device_table_map, device)->DestroyDescriptorPool(device, descriptorPool, pAllocator);
 }
@@ -3496,8 +3497,8 @@
     layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
     bool skip_call = false;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
-    skip_call |= ValidateNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00080);
+    skip_call |= ValidateObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, true, VALIDATION_ERROR_00081);
     lock.unlock();
     if (skip_call) {
         return;
@@ -3512,11 +3513,11 @@
         del_itr = itr++;
         if (pNode->parent_object == reinterpret_cast<uint64_t &>(commandPool)) {
             skip_call |= ValidateCommandBuffer(device, commandPool, reinterpret_cast<VkCommandBuffer>((*del_itr).first));
-            DestroyDispatchableObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
-                                      VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT);
+            DestroyObject(device, reinterpret_cast<VkCommandBuffer>((*del_itr).first),
+                                      VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, nullptr);
         }
     }
-    DestroyNonDispatchableObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT);
+    DestroyObject(device, commandPool, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT, pAllocator);
     lock.unlock();
     get_dispatch_table(ot_device_table_map, device)->DestroyCommandPool(device, commandPool, pAllocator);
 }
@@ -3525,7 +3526,7 @@
                                                      VkImage *pSwapchainImages) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
     lock.unlock();
     if (skip_call) {
         return VK_ERROR_VALIDATION_FAILED_EXT;
@@ -3547,33 +3548,34 @@
                                                        const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00519);
     if (pCreateInfos) {
         for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
             if (pCreateInfos[idx0].basePipelineHandle) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].basePipelineHandle,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].basePipelineHandle,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
             }
             if (pCreateInfos[idx0].layout) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].layout,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].layout,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
             }
             if (pCreateInfos[idx0].pStages) {
                 for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
                     if (pCreateInfos[idx0].pStages[idx1].module) {
-                        skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].pStages[idx1].module,
+                        skip_call |= ValidateObject(device, pCreateInfos[idx0].pStages[idx1].module,
                                                                    VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
                     }
                 }
             }
             if (pCreateInfos[idx0].renderPass) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].renderPass,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].renderPass,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT, false);
             }
         }
     }
     if (pipelineCache) {
-        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        skip_call |=
+            ValidateObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, true, VALIDATION_ERROR_00520);
     }
     lock.unlock();
     if (skip_call) {
@@ -3584,7 +3586,7 @@
     lock.lock();
     if (result == VK_SUCCESS) {
         for (uint32_t idx2 = 0; idx2 < createInfoCount; ++idx2) {
-            CreateNonDispatchableObject(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+            CreateObject(device, pPipelines[idx2], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, pAllocator);
         }
     }
     lock.unlock();
@@ -3596,25 +3598,26 @@
                                                       const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
     bool skip_call = VK_FALSE;
     std::unique_lock<std::mutex> lock(global_lock);
-    skip_call |= ValidateDispatchableObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false, VALIDATION_ERROR_00486);
     if (pCreateInfos) {
         for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
             if (pCreateInfos[idx0].basePipelineHandle) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].basePipelineHandle,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].basePipelineHandle,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, true);
             }
             if (pCreateInfos[idx0].layout) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].layout,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].layout,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT, false);
             }
             if (pCreateInfos[idx0].stage.module) {
-                skip_call |= ValidateNonDispatchableObject(device, pCreateInfos[idx0].stage.module,
+                skip_call |= ValidateObject(device, pCreateInfos[idx0].stage.module,
                                                            VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT, false);
             }
         }
     }
     if (pipelineCache) {
-        skip_call |= ValidateNonDispatchableObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, false);
+        skip_call |=
+            ValidateObject(device, pipelineCache, VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT, true, VALIDATION_ERROR_00487);
     }
     lock.unlock();
     if (skip_call) {
@@ -3625,13 +3628,135 @@
     lock.lock();
     if (result == VK_SUCCESS) {
         for (uint32_t idx1 = 0; idx1 < createInfoCount; ++idx1) {
-            CreateNonDispatchableObject(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT);
+            CreateObject(device, pPipelines[idx1], VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT, pAllocator);
         }
     }
     lock.unlock();
     return result;
 }
 
+// VK_EXT_debug_marker Extension
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->DebugMarkerSetObjectTagEXT(device, pTagInfo);
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->DebugMarkerSetObjectNameEXT(device, pNameInfo);
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
+    }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerEndEXT(VkCommandBuffer commandBuffer) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDebugMarkerEndEXT(commandBuffer);
+    }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT, false);
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, commandBuffer)->CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
+    }
+}
+
+// VK_NV_external_memory_capabilities Extension
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV(
+    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
+    VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+    VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
+
+    bool skip_call = false;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        skip_call |= ValidateObject(physicalDevice, physicalDevice, VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT, false);
+    }
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_instance_table_map, physicalDevice)
+                          ->GetPhysicalDeviceExternalImageFormatPropertiesNV(physicalDevice, format, type, tiling, usage, flags,
+                                                                             externalHandleType, pExternalImageFormatProperties);
+    return result;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+// VK_NV_external_memory_win32 Extension
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
+                                                      VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(device, device, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(device, memory, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT, false);
+    lock.unlock();
+    if (skip_call) {
+        return VK_ERROR_VALIDATION_FAILED_EXT;
+    }
+    VkResult result = get_dispatch_table(ot_device_table_map, device)->GetMemoryWin32HandleNV(device, memory, handleType, pHandle);
+    return result;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+// VK_AMD_draw_indirect_count Extension
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                                   VkBuffer countBuffer, VkDeviceSize countBufferOffset, uint32_t maxDrawCount,
+                                                   uint32_t stride) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, commandBuffer)
+            ->CmdDrawIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+    }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDrawIndexedIndirectCountAMD(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset,
+                                                          VkBuffer countBuffer, VkDeviceSize countBufferOffset,
+                                                          uint32_t maxDrawCount, uint32_t stride) {
+    bool skip_call = VK_FALSE;
+    std::unique_lock<std::mutex> lock(global_lock);
+    skip_call |= ValidateObject(commandBuffer, commandBuffer, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, false);
+    skip_call |= ValidateObject(commandBuffer, buffer, VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT, false);
+    lock.unlock();
+    if (!skip_call) {
+        get_dispatch_table(ot_device_table_map, commandBuffer)
+            ->CmdDrawIndexedIndirectCountAMD(commandBuffer, buffer, offset, countBuffer, countBufferOffset, maxDrawCount, stride);
+    }
+}
+
+
 static inline PFN_vkVoidFunction InterceptCoreDeviceCommand(const char *name) {
     if (!name || name[0] != 'v' || name[1] != 'k')
         return NULL;
@@ -3879,6 +4004,24 @@
         return (PFN_vkVoidFunction)CmdEndRenderPass;
     if (!strcmp(name, "CmdExecuteCommands"))
         return (PFN_vkVoidFunction)CmdExecuteCommands;
+    if (!strcmp(name, "DebugMarkerSetObjectTagEXT"))
+        return (PFN_vkVoidFunction)DebugMarkerSetObjectTagEXT;
+    if (!strcmp(name, "DebugMarkerSetObjectNameEXT"))
+        return (PFN_vkVoidFunction)DebugMarkerSetObjectNameEXT;
+    if (!strcmp(name, "CmdDebugMarkerBeginEXT"))
+        return (PFN_vkVoidFunction)CmdDebugMarkerBeginEXT;
+    if (!strcmp(name, "CmdDebugMarkerEndEXT"))
+        return (PFN_vkVoidFunction)CmdDebugMarkerEndEXT;
+    if (!strcmp(name, "CmdDebugMarkerInsertEXT"))
+        return (PFN_vkVoidFunction)CmdDebugMarkerInsertEXT;
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    if (!strcmp(name, "GetMemoryWin32HandleNV"))
+        return (PFN_vkVoidFunction)GetMemoryWin32HandleNV;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+    if (!strcmp(name, "CmdDrawIndirectCountAMD"))
+        return (PFN_vkVoidFunction)CmdDrawIndirectCountAMD;
+    if (!strcmp(name, "CmdDrawIndexedIndirectCountAMD"))
+        return (PFN_vkVoidFunction)CmdDrawIndexedIndirectCountAMD;
 
     return NULL;
 }
@@ -3917,6 +4060,8 @@
         return (PFN_vkVoidFunction)EnumerateDeviceLayerProperties;
     if (!strcmp(name, "GetPhysicalDeviceSparseImageFormatProperties"))
         return (PFN_vkVoidFunction)GetPhysicalDeviceSparseImageFormatProperties;
+    if (!strcmp(name, "GetPhysicalDeviceExternalImageFormatPropertiesNV"))
+        return (PFN_vkVoidFunction)GetPhysicalDeviceExternalImageFormatPropertiesNV;
 
     return NULL;
 }
diff --git a/layers/object_tracker.h b/layers/object_tracker.h
index c4088a9..729e613 100644
--- a/layers/object_tracker.h
+++ b/layers/object_tracker.h
@@ -39,6 +39,7 @@
     OBJTRACK_INVALID_OBJECT,           // Object used that has never been created
     OBJTRACK_DESCRIPTOR_POOL_MISMATCH, // Descriptor Pools specified incorrectly
     OBJTRACK_COMMAND_POOL_MISMATCH,    // Command Pools specified incorrectly
+    OBJTRACK_ALLOCATOR_MISMATCH,       // Created with custom allocator but destroyed without
 };
 
 // Object Status -- used to track state of individual objects
@@ -52,6 +53,7 @@
     OBJSTATUS_DEPTH_STENCIL_BOUND = 0x00000010,      // Viewport state object has been bound
     OBJSTATUS_GPU_MEM_MAPPED = 0x00000020,           // Memory object is currently mapped
     OBJSTATUS_COMMAND_BUFFER_SECONDARY = 0x00000040, // Command Buffer is of type SECONDARY
+    OBJSTATUS_CUSTOM_ALLOCATOR = 0x00000080,         // Allocated with custom allocator
 };
 
 // Object and state information structure
diff --git a/layers/parameter_validation.cpp b/layers/parameter_validation.cpp
index 2bc8d38..1306217 100644
--- a/layers/parameter_validation.cpp
+++ b/layers/parameter_validation.cpp
@@ -2361,6 +2361,17 @@
     assert(device_data != nullptr);
     debug_report_data *report_data = device_data->report_data;
 
+    // TODO: Add check for VALIDATION_ERROR_00660
+    // TODO: Add check for VALIDATION_ERROR_00661
+    // TODO: Add check for VALIDATION_ERROR_00662
+    // TODO: Add check for VALIDATION_ERROR_00670
+    // TODO: Add check for VALIDATION_ERROR_00671
+    // TODO: Add check for VALIDATION_ERROR_00672
+    // TODO: Add check for VALIDATION_ERROR_00673
+    // TODO: Add check for VALIDATION_ERROR_00674
+    // TODO: Add check for VALIDATION_ERROR_00675
+    // TODO: Note that the above errors need to be generated from the next function, which is codegened.
+    // TODO: Add check for VALIDATION_ERROR_00663
     skip_call |= parameter_validation_vkCreateBuffer(report_data, pCreateInfo, pAllocator, pBuffer);
 
     if (pCreateInfo != nullptr) {
@@ -2368,20 +2379,22 @@
         if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
             // If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1
             if (pCreateInfo->queueFamilyIndexCount <= 1) {
-                skip_call |=
-                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                            INVALID_USAGE, LayerName, "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
-                                                      "pCreateInfo->queueFamilyIndexCount must be greater than 1");
+                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
+                                     __LINE__, VALIDATION_ERROR_00665, LayerName,
+                                     "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
+                                     "pCreateInfo->queueFamilyIndexCount must be greater than 1. %s",
+                                     validation_error_map[VALIDATION_ERROR_00665]);
             }
 
             // If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of
             // queueFamilyIndexCount uint32_t values
             if (pCreateInfo->pQueueFamilyIndices == nullptr) {
                 skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                                     __LINE__, REQUIRED_PARAMETER, LayerName,
+                                     __LINE__, VALIDATION_ERROR_00664, LayerName,
                                      "vkCreateBuffer: if pCreateInfo->sharingMode is VK_SHARING_MODE_CONCURRENT, "
                                      "pCreateInfo->pQueueFamilyIndices must be a pointer to an array of "
-                                     "pCreateInfo->queueFamilyIndexCount uint32_t values");
+                                     "pCreateInfo->queueFamilyIndexCount uint32_t values. %s",
+                                     validation_error_map[VALIDATION_ERROR_00664]);
             }
 
             // Ensure that the queue family indices were specified at device creation
@@ -5077,6 +5090,112 @@
     return result;
 }
 
+// VK_EXT_debug_marker Extension
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectTagEXT(VkDevice device, VkDebugMarkerObjectTagInfoEXT *pTagInfo) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkDebugMarkerSetObjectTagEXT(my_data->report_data, pTagInfo);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, device)->DebugMarkerSetObjectTagEXT(device, pTagInfo);
+
+        validate_result(my_data->report_data, "vkDebugMarkerSetObjectTagEXT", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL DebugMarkerSetObjectNameEXT(VkDevice device, VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkDebugMarkerSetObjectNameEXT(my_data->report_data, pNameInfo);
+
+    if (!skip_call) {
+        VkResult result = get_dispatch_table(pc_device_table_map, device)->DebugMarkerSetObjectNameEXT(device, pNameInfo);
+
+        validate_result(my_data->report_data, "vkDebugMarkerSetObjectNameEXT", result);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerBeginEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkCmdDebugMarkerBeginEXT(my_data->report_data, pMarkerInfo);
+
+    if (!skip_call) {
+        get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDebugMarkerBeginEXT(commandBuffer, pMarkerInfo);
+    }
+}
+
+VKAPI_ATTR void VKAPI_CALL CmdDebugMarkerInsertEXT(VkCommandBuffer commandBuffer, VkDebugMarkerMarkerInfoEXT *pMarkerInfo) {
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(commandBuffer), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkCmdDebugMarkerInsertEXT(my_data->report_data, pMarkerInfo);
+
+    if (!skip_call) {
+        get_dispatch_table(pc_device_table_map, commandBuffer)->CmdDebugMarkerInsertEXT(commandBuffer, pMarkerInfo);
+    }
+}
+
+// VK_NV_external_memory_capabilities Extension
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceExternalImageFormatPropertiesNV(
+    VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
+    VkImageCreateFlags flags, VkExternalMemoryHandleTypeFlagsNV externalHandleType,
+    VkExternalImageFormatPropertiesNV *pExternalImageFormatProperties) {
+
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
+        my_data->report_data, format, type, tiling, usage, flags, externalHandleType, pExternalImageFormatProperties);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_instance_table_map, physicalDevice)
+                     ->GetPhysicalDeviceExternalImageFormatPropertiesNV(physicalDevice, format, type, tiling, usage, flags,
+                                                                        externalHandleType, pExternalImageFormatProperties);
+
+        validate_result(my_data->report_data, "vkGetPhysicalDeviceExternalImageFormatPropertiesNV", result);
+    }
+
+    return result;
+}
+
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+// VK_NV_external_memory_win32 Extension
+VKAPI_ATTR VkResult VKAPI_CALL GetMemoryWin32HandleNV(VkDevice device, VkDeviceMemory memory,
+                                                      VkExternalMemoryHandleTypeFlagsNV handleType, HANDLE *pHandle) {
+
+    VkResult result = VK_ERROR_VALIDATION_FAILED_EXT;
+    bool skip_call = false;
+    layer_data *my_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    assert(my_data != NULL);
+
+    skip_call |= parameter_validation_vkGetMemoryWin32HandleNV(my_data->report_data, memory, handleType, pHandle);
+
+    if (!skip_call) {
+        result = get_dispatch_table(pc_device_table_map, device)->GetMemoryWin32HandleNV(device, memory, handleType, pHandle);
+    }
+
+    return result;
+}
+#endif // VK_USE_PLATFORM_WIN32_KHR
+
+
+
 static PFN_vkVoidFunction intercept_core_instance_command(const char *name);
 
 static PFN_vkVoidFunction intercept_core_device_command(const char *name);
@@ -5156,6 +5275,7 @@
         {"vkEnumerateDeviceLayerProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties)},
         {"vkEnumerateInstanceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties)},
         {"vkEnumerateDeviceExtensionProperties", reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties)},
+        {"vkGetPhysicalDeviceExternalImageFormatPropertiesNV", reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceExternalImageFormatPropertiesNV) },
     };
 
     for (size_t i = 0; i < ARRAY_SIZE(core_instance_commands); i++) {
@@ -5288,7 +5408,15 @@
         {"vkCmdNextSubpass", reinterpret_cast<PFN_vkVoidFunction>(CmdNextSubpass)},
         {"vkCmdExecuteCommands", reinterpret_cast<PFN_vkVoidFunction>(CmdExecuteCommands)},
         {"vkCmdEndRenderPass", reinterpret_cast<PFN_vkVoidFunction>(CmdEndRenderPass)},
-    };
+        {"vkDebugMarkerSetObjectTagEXT", reinterpret_cast<PFN_vkVoidFunction>(DebugMarkerSetObjectTagEXT) },
+        {"vkDebugMarkerSetObjectNameEXT", reinterpret_cast<PFN_vkVoidFunction>(DebugMarkerSetObjectNameEXT) },
+        {"vkCmdDebugMarkerBeginEXT", reinterpret_cast<PFN_vkVoidFunction>(CmdDebugMarkerBeginEXT) },
+        {"vkCmdDebugMarkerInsertEXT", reinterpret_cast<PFN_vkVoidFunction>(CmdDebugMarkerInsertEXT) },
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        {"vkGetMemoryWin32HandleNV", reinterpret_cast<PFN_vkVoidFunction>(GetMemoryWin32HandleNV) },
+#endif // VK_USE_PLATFORM_WIN32_KHR
+};
+
 
     for (size_t i = 0; i < ARRAY_SIZE(core_device_commands); i++) {
         if (!strcmp(core_device_commands[i].name, name))
diff --git a/layers/parameter_validation_utils.h b/layers/parameter_validation_utils.h
index a1d2e1f..9d6082b 100644
--- a/layers/parameter_validation_utils.h
+++ b/layers/parameter_validation_utils.h
@@ -28,6 +28,9 @@
 #include "vulkan/vulkan.h"
 #include "vk_enum_string_helper.h"
 #include "vk_layer_logging.h"
+#include "vk_validation_error_messages.h"
+
+#include "parameter_name.h"
 
 #include "parameter_name.h"
 
@@ -174,7 +177,7 @@
     bool skip_call = false;
 
     // Count parameters not tagged as optional cannot be 0
-    if ((count == 0) && countRequired) {
+    if (countRequired && (count == 0)) {
         skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
                             REQUIRED_PARAMETER, LayerName, "%s: parameter %s must be greater than 0", apiName,
                             countName.get_name().c_str());
@@ -795,7 +798,7 @@
 * @param value VkResult value to validate.
 */
 static void validate_result(debug_report_data *report_data, const char *apiName, VkResult result) {
-    if (result < 0) {
+    if (result < 0 && result != VK_ERROR_VALIDATION_FAILED_EXT) {
         std::string resultName = string_VkResult(result);
 
         if (resultName == UnsupportedResultString) {
diff --git a/layers/spec.py b/layers/spec.py
new file mode 100644
index 0000000..bdd306b
--- /dev/null
+++ b/layers/spec.py
@@ -0,0 +1,552 @@
+#!/usr/bin/python3 -i
+
+import sys
+import xml.etree.ElementTree as etree
+import urllib2
+
+#############################
+# spec.py script
+#
+# Overview - this script is intended to generate validation error codes and message strings from the xhtml version of
+#  the specification. In addition to generating the header file, it provides a number of corrollary services to aid in
+#  generating/updating the header.
+#
+# Ideal flow - Not there currently, but the ideal flow for this script would be that you run the script, it pulls the
+#  latest spec, compares it to the current set of generated error codes, and makes any updates as needed
+#
+# Current flow - the current flow acheives all of the ideal flow goals, but with more steps than are desired
+#  1. Get the spec - right now spec has to be manually generated or pulled from the web
+#  2. Generate header from spec - This is done in a single command line
+#  3. Generate database file from spec - Can be done along with step #2 above, the database file contains a list of
+#      all error enums and message strings, along with some other info on if those errors are implemented/tested
+#  4. Update header using a given database file as the root and a new spec file as goal - This makes sure that existing
+#      errors keep the same enum identifier while also making sure that new errors get a unique_id that continues on
+#      from the end of the previous highest unique_id.
+#
+# TODO:
+#  1. Improve string matching to add more automation for figuring out which messages are changed vs. completely new
+#
+#############################
+
+
+spec_filename = "vkspec.html" # can override w/ '-spec <filename>' option
+out_filename = "vk_validation_error_messages.h" # can override w/ '-out <filename>' option
+db_filename = "vk_validation_error_database.txt" # can override w/ '-gendb <filename>' option
+gen_db = False # set to True when '-gendb <filename>' option provided
+spec_compare = False # set to True with '-compare <db_filename>' option
+# This is the root spec link that is used in error messages to point users to spec sections
+#old_spec_url = "https://www.khronos.org/registry/vulkan/specs/1.0/xhtml/vkspec.html"
+spec_url = "https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html"
+# After the custom validation error message, this is the prefix for the standard message that includes the
+#  spec valid usage language as well as the link to nearest section of spec to that language
+error_msg_prefix = "For more information refer to Vulkan Spec Section "
+ns = {'ns': 'http://www.w3.org/1999/xhtml'}
+validation_error_enum_name = "VALIDATION_ERROR_"
+# Dict of new enum values that should be forced to remap to old handles, explicitly set by -remap option
+remap_dict = {}
+
+def printHelp():
+    print "Usage: python spec.py [-spec <specfile.html>] [-out <headerfile.h>] [-gendb <databasefile.txt>] [-compare <databasefile.txt>] [-update] [-remap <new_id-old_id,count>] [-help]"
+    print "\n Default script behavior is to parse the specfile and generate a header of unique error enums and corresponding error messages based on the specfile.\n"
+    print "  Default specfile is from online at %s" % (spec_url)
+    print "  Default headerfile is %s" % (out_filename)
+    print "  Default databasefile is %s" % (db_filename)
+    print "\nIf '-gendb' option is specified then a database file is generated to default file or <databasefile.txt> if supplied. The database file stores"
+    print "  the list of enums and their error messages."
+    print "\nIf '-compare' option is specified then the given database file will be read in as the baseline for generating the new specfile"
+    print "\nIf '-update' option is specified this triggers the master flow to automate updating header and database files using default db file as baseline"
+    print "  and online spec file as the latest. The default header and database files will be updated in-place for review and commit to the git repo."
+    print "\nIf '-remap' option is specified it supplies forced remapping from new enum ids to old enum ids. This should only be specified along with -update"
+    print "  option. Starting at newid and remapping to oldid, count ids will be remapped. Default count is '1' and use ':' to specify multiple remappings."
+
+class Specification:
+    def __init__(self):
+        self.tree   = None
+        self.val_error_dict = {} # string for enum is key that references 'error_msg' and 'api'
+        self.error_db_dict = {} # dict of previous error values read in from database file
+        self.delimiter = '~^~' # delimiter for db file
+        self.copyright = """/* THIS FILE IS GENERATED.  DO NOT EDIT. */
+
+/*
+ * Vulkan
+ *
+ * Copyright (c) 2016 Google Inc.
+ * Copyright (c) 2016 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>
+ */"""
+    def _checkInternetSpec(self):
+        """Verify that we can access the spec online"""
+        try:
+            online = urllib2.urlopen(spec_url,timeout=1)
+            return True
+        except urllib2.URLError as err:
+            return False
+        return False
+    def loadFile(self, online=True, spec_file=spec_filename):
+        """Load an API registry XML file into a Registry object and parse it"""
+        # Check if spec URL is available
+        if (online and self._checkInternetSpec()):
+            print "Using spec from online at %s" % (spec_url)
+            self.tree = etree.parse(urllib2.urlopen(spec_url))
+        else:
+            print "Using local spec %s" % (spec_file)
+            self.tree = etree.parse(spec_file)
+        #self.tree.write("tree_output.xhtml")
+        #self.tree = etree.parse("tree_output.xhtml")
+        self.parseTree()
+    def updateDict(self, updated_dict):
+        """Assign internal dict to use updated_dict"""
+        self.val_error_dict = updated_dict
+    def parseTree(self):
+        """Parse the registry Element, once created"""
+        print "Parsing spec file..."
+        unique_enum_id = 0
+        self.root = self.tree.getroot()
+        #print "ROOT: %s" % self.root
+        prev_heading = '' # Last seen section heading or sub-heading
+        prev_link = '' # Last seen link id within the spec
+        api_function = '' # API call that a check appears under
+        error_strings = set() # Flag any exact duplicate error strings and skip them
+        for tag in self.root.iter(): # iterate down tree
+            # Grab most recent section heading and link
+            if tag.tag in ['{http://www.w3.org/1999/xhtml}h2', '{http://www.w3.org/1999/xhtml}h3']:
+                if tag.get('class') != 'title':
+                    continue
+                #print "Found heading %s" % (tag.tag)
+                prev_heading = "".join(tag.itertext())
+                # Insert a space between heading number & title
+                sh_list = prev_heading.rsplit('.', 1)
+                prev_heading = '. '.join(sh_list)
+                prev_link = tag[0].get('id')
+                #print "Set prev_heading %s to have link of %s" % (prev_heading.encode("ascii", "ignore"), prev_link.encode("ascii", "ignore"))
+            elif tag.tag == '{http://www.w3.org/1999/xhtml}a': # grab any intermediate links
+                if tag.get('id') != None:
+                    prev_link = tag.get('id')
+                    #print "Updated prev link to %s" % (prev_link)
+            elif tag.tag == '{http://www.w3.org/1999/xhtml}pre' and tag.get('class') == 'programlisting':
+                # Check and see if this is API function
+                code_text = "".join(tag.itertext()).replace('\n', '')
+                code_text_list = code_text.split()
+                if len(code_text_list) > 1 and code_text_list[1].startswith('vk'):
+                    api_function = code_text_list[1].strip('(')
+                    print "Found API function: %s" % (api_function)
+            elif tag.tag == '{http://www.w3.org/1999/xhtml}div' and tag.get('class') == 'sidebar':
+                # parse down sidebar to check for valid usage cases
+                valid_usage = False
+                for elem in tag.iter():
+                    if elem.tag == '{http://www.w3.org/1999/xhtml}strong' and None != elem.text and 'Valid Usage' in elem.text:
+                        valid_usage = True
+                    elif valid_usage and elem.tag == '{http://www.w3.org/1999/xhtml}li': # grab actual valid usage requirements
+                        error_msg_str = "%s '%s' which states '%s' (%s#%s)" % (error_msg_prefix, prev_heading, "".join(elem.itertext()).replace('\n', ''), spec_url, prev_link)
+                        # Some txt has multiple spaces so split on whitespace and join w/ single space
+                        error_msg_str = " ".join(error_msg_str.split())
+                        if error_msg_str in error_strings:
+                            print "WARNING: SKIPPING adding repeat entry for string. Please review spec and file issue as appropriate. Repeat string is: %s" % (error_msg_str)
+                        else:
+                            error_strings.add(error_msg_str)
+                            enum_str = "%s%05d" % (validation_error_enum_name, unique_enum_id)
+                            # TODO : '\' chars in spec error messages are most likely bad spec txt that needs to be updated
+                            self.val_error_dict[enum_str] = {}
+                            self.val_error_dict[enum_str]['error_msg'] = error_msg_str.encode("ascii", "ignore").replace("\\", "/")
+                            self.val_error_dict[enum_str]['api'] = api_function
+                            unique_enum_id = unique_enum_id + 1
+        #print "Validation Error Dict has a total of %d unique errors and contents are:\n%s" % (unique_enum_id, self.val_error_dict)
+    def genHeader(self, header_file):
+        """Generate a header file based on the contents of a parsed spec"""
+        print "Generating header %s..." % (header_file)
+        file_contents = []
+        file_contents.append(self.copyright)
+        file_contents.append('\n#pragma once')
+        file_contents.append('#include <unordered_map>')
+        file_contents.append('\n// enum values for unique validation error codes')
+        file_contents.append('//  Corresponding validation error message for each enum is given in the mapping table below')
+        file_contents.append('//  When a given error occurs, these enum values should be passed to the as the messageCode')
+        file_contents.append('//  parameter to the PFN_vkDebugReportCallbackEXT function')
+        enum_decl = ['enum UNIQUE_VALIDATION_ERROR_CODE {']
+        error_string_map = ['static std::unordered_map<int, char const *const> validation_error_map{']
+        for enum in sorted(self.val_error_dict):
+            #print "Header enum is %s" % (enum)
+            enum_decl.append('    %s = %d,' % (enum, int(enum.split('_')[-1])))
+            error_string_map.append('    {%s, "%s"},' % (enum, self.val_error_dict[enum]['error_msg']))
+        enum_decl.append('    %sMAX_ENUM = %d,' % (validation_error_enum_name, int(enum.split('_')[-1]) + 1))
+        enum_decl.append('};')
+        error_string_map.append('};\n')
+        file_contents.extend(enum_decl)
+        file_contents.append('\n// Mapping from unique validation error enum to the corresponding error message')
+        file_contents.append('// The error message should be appended to the end of a custom error message that is passed')
+        file_contents.append('// as the pMessage parameter to the PFN_vkDebugReportCallbackEXT function')
+        file_contents.extend(error_string_map)
+        #print "File contents: %s" % (file_contents)
+        with open(header_file, "w") as outfile:
+            outfile.write("\n".join(file_contents))
+    def analyze(self):
+        """Print out some stats on the valid usage dict"""
+        # Create dict for # of occurences of identical strings
+        str_count_dict = {}
+        unique_id_count = 0
+        for enum in self.val_error_dict:
+            err_str = self.val_error_dict[enum]['error_msg']
+            if err_str in str_count_dict:
+                print "Found repeat error string"
+                str_count_dict[err_str] = str_count_dict[err_str] + 1
+            else:
+                str_count_dict[err_str] = 1
+            unique_id_count = unique_id_count + 1
+        print "Processed %d unique_ids" % (unique_id_count)
+        repeat_string = 0
+        for es in str_count_dict:
+            if str_count_dict[es] > 1:
+                repeat_string = repeat_string + 1
+                print "String '%s' repeated %d times" % (es, repeat_string)
+        print "Found %d repeat strings" % (repeat_string)
+    def genDB(self, db_file):
+        """Generate a database of check_enum, check_coded?, testname, error_string"""
+        db_lines = []
+        # Write header for database file
+        db_lines.append("# This is a database file with validation error check information")
+        db_lines.append("# Comments are denoted with '#' char")
+        db_lines.append("# The format of the lines is:")
+        db_lines.append("# <error_enum>%s<check_implemented>%s<testname>%s<api>%s<errormsg>%s<note>" % (self.delimiter, self.delimiter, self.delimiter, self.delimiter, self.delimiter))
+        db_lines.append("# error_enum: Unique error enum for this check of format %s<uniqueid>" % validation_error_enum_name)
+        db_lines.append("# check_implemented: 'Y' if check has been implemented in layers, 'U' for unknown, or 'N' for not implemented")
+        db_lines.append("# testname: Name of validation test for this check, 'Unknown' for unknown, or 'None' if not implmented")
+        db_lines.append("# api: Vulkan API function that this check is related to")
+        db_lines.append("# errormsg: The unique error message for this check that includes spec language and link")
+        db_lines.append("# note: Free txt field with any custom notes related to the check in question")
+        for enum in sorted(self.val_error_dict):
+            # Default to unknown if check or test are implemented, then update below if appropriate
+            implemented = 'U'
+            testname = 'Unknown'
+            note = ''
+            # If we have an existing db entry for this enum, use its implemented/testname values
+            if enum in self.error_db_dict:
+                implemented = self.error_db_dict[enum]['check_implemented']
+                testname = self.error_db_dict[enum]['testname']
+                note = self.error_db_dict[enum]['note']
+            #print "delimiter: %s, id: %s, str: %s" % (self.delimiter, enum, self.val_error_dict[enum])
+            # No existing entry so default to N for implemented and None for testname
+            db_lines.append("%s%s%s%s%s%s%s%s%s%s%s" % (enum, self.delimiter, implemented, self.delimiter, testname, self.delimiter, self.val_error_dict[enum]['api'], self.delimiter, self.val_error_dict[enum]['error_msg'], self.delimiter, note))
+        print "Generating database file %s" % (db_file)
+        with open(db_file, "w") as outfile:
+            outfile.write("\n".join(db_lines))
+            outfile.write("\n")
+    def readDB(self, db_file):
+        """Read a db file into a dict, format of each line is <enum><implemented Y|N?><testname><errormsg>"""
+        db_dict = {} # This is a simple db of just enum->errormsg, the same as is created from spec
+        max_id = 0
+        with open(db_file, "r") as infile:
+            for line in infile:
+                if line.startswith('#'):
+                    continue
+                line = line.strip()
+                db_line = line.split(self.delimiter)
+                if len(db_line) != 6:
+                    print "ERROR: Bad database line doesn't have 6 elements: %s" % (line)
+                error_enum = db_line[0]
+                implemented = db_line[1]
+                testname = db_line[2]
+                api = db_line[3]
+                error_str = db_line[4]
+                note = db_line[5]
+                db_dict[error_enum] = error_str
+                # Also read complete database contents into our class var for later use
+                self.error_db_dict[error_enum] = {}
+                self.error_db_dict[error_enum]['check_implemented'] = implemented
+                self.error_db_dict[error_enum]['testname'] = testname
+                self.error_db_dict[error_enum]['api'] = api
+                self.error_db_dict[error_enum]['error_string'] = error_str
+                self.error_db_dict[error_enum]['note'] = note
+                unique_id = int(db_line[0].split('_')[-1])
+                if unique_id > max_id:
+                    max_id = unique_id
+        return (db_dict, max_id)
+    # Compare unique ids from original database to data generated from updated spec
+    # 1. If a new id and error code exactly match original, great
+    # 2. If new id is not in original, but exact error code is, need to use original error code
+    # 3. If new id and new error are not in original, make sure new id picks up from end of original list
+    # 4. If new id in original, but error strings don't match then:
+    #   4a. If error string has exact match in original, update new to use original
+    #   4b. If error string not in original, may be updated error message, manually address
+    def compareDB(self, orig_error_msg_dict, max_id):
+        """Compare orig database dict to new dict, report out findings, and return potential new dict for parsed spec"""
+        # First create reverse dicts of err_strings to IDs
+        next_id = max_id + 1
+        orig_err_to_id_dict = {}
+        # Create an updated dict in-place that will be assigned to self.val_error_dict when done
+        updated_val_error_dict = {}
+        for enum in orig_error_msg_dict:
+            orig_err_to_id_dict[orig_error_msg_dict[enum]] = enum
+        new_err_to_id_dict = {}
+        for enum in self.val_error_dict:
+            new_err_to_id_dict[self.val_error_dict[enum]['error_msg']] = enum
+        ids_parsed = 0
+        # Values to be used for the update dict
+        update_enum = ''
+        update_msg = ''
+        update_api = ''
+        # Now parse through new dict and figure out what to do with non-matching things
+        for enum in sorted(self.val_error_dict):
+            ids_parsed = ids_parsed + 1
+            enum_list = enum.split('_') # grab sections of enum for use below
+            # Default update values to be the same
+            update_enum = enum
+            update_msg = self.val_error_dict[enum]['error_msg']
+            update_api = self.val_error_dict[enum]['api']
+            # Any user-forced remap takes precendence
+            if enum_list[-1] in remap_dict:
+                enum_list[-1] = remap_dict[enum_list[-1]]
+                new_enum = "_".join(enum_list)
+                print "NOTE: Using user-supplied remap to force %s to be %s" % (enum, new_enum)
+                update_enum = new_enum
+            elif enum in orig_error_msg_dict:
+                if self.val_error_dict[enum]['error_msg'] == orig_error_msg_dict[enum]:
+                    print "Exact match for enum %s" % (enum)
+                    # Nothing to see here
+                    if enum in updated_val_error_dict:
+                        print "ERROR: About to overwrite entry for %s" % (enum)
+                elif self.val_error_dict[enum]['error_msg'] in orig_err_to_id_dict:
+                    # Same value w/ different error id, need to anchor to original id
+                    print "Need to switch new id %s to original id %s" % (enum, orig_err_to_id_dict[self.val_error_dict[enum]['error_msg']])
+                    # Update id at end of new enum to be same id from original enum
+                    enum_list[-1] = orig_err_to_id_dict[self.val_error_dict[enum]['error_msg']].split('_')[-1]
+                    new_enum = "_".join(enum_list)
+                    if new_enum in updated_val_error_dict:
+                        print "ERROR: About to overwrite entry for %s" % (new_enum)
+                    update_enum = new_enum
+                else:
+                    # No error match:
+                    #  First check if only link has changed, in which case keep ID but update message
+                    orig_msg_list = orig_error_msg_dict[enum].split('(', 1)
+                    new_msg_list = self.val_error_dict[enum]['error_msg'].split('(', 1)
+                    if orig_msg_list[0] == new_msg_list[0]: # Msg is same bug link has changed, keep enum & update msg
+                        print "NOTE: Found that only spec link changed for %s so keeping same id w/ new link" % (enum)
+                    #  This seems to be a new error so need to pick it up from end of original unique ids & flag for review
+                    else:
+                        enum_list[-1] = "%05d" % (next_id)
+                        new_enum = "_".join(enum_list)
+                        next_id = next_id + 1
+                        print "MANUALLY VERIFY: Updated new enum %s to be unique %s. Make sure new error msg is actually unique and not just changed" % (enum, new_enum)
+                        print "   New error string: %s" % (self.val_error_dict[enum]['error_msg'])
+                        if new_enum in updated_val_error_dict:
+                            print "ERROR: About to overwrite entry for %s" % (new_enum)
+                        update_enum = new_enum
+            else: # new enum is not in orig db
+                if self.val_error_dict[enum]['error_msg'] in orig_err_to_id_dict:
+                    print "New enum %s not in orig dict, but exact error message matches original unique id %s" % (enum, orig_err_to_id_dict[self.val_error_dict[enum]['error_msg']])
+                    # Update new unique_id to use original
+                    enum_list[-1] = orig_err_to_id_dict[self.val_error_dict[enum]['error_msg']].split('_')[-1]
+                    new_enum = "_".join(enum_list)
+                    if new_enum in updated_val_error_dict:
+                        print "ERROR: About to overwrite entry for %s" % (new_enum)
+                    update_enum = new_enum
+                else:
+                    enum_list[-1] = "%05d" % (next_id)
+                    new_enum = "_".join(enum_list)
+                    next_id = next_id + 1
+                    print "Completely new id and error code, update new id from %s to unique %s" % (enum, new_enum)
+                    if new_enum in updated_val_error_dict:
+                        print "ERROR: About to overwrite entry for %s" % (new_enum)
+                    update_enum = new_enum
+            updated_val_error_dict[update_enum] = {}
+            updated_val_error_dict[update_enum]['error_msg'] = update_msg
+            updated_val_error_dict[update_enum]['api'] = update_api
+        # Assign parsed dict to be the udpated dict based on db compare
+        print "In compareDB parsed %d entries" % (ids_parsed)
+        return updated_val_error_dict
+    def validateUpdateDict(self, update_dict):
+        """Compare original dict vs. update dict and make sure that all of the checks are still there"""
+        # Currently just make sure that the same # of checks as the original checks are there
+        #orig_ids = {}
+        orig_id_count = len(self.val_error_dict)
+        #update_ids = {}
+        update_id_count = len(update_dict)
+        if orig_id_count != update_id_count:
+            print "Original dict had %d unique_ids, but updated dict has %d!" % (orig_id_count, update_id_count)
+            return False
+        print "Original dict and updated dict both have %d unique_ids. Great!" % (orig_id_count)
+        return True
+        # TODO : include some more analysis
+
+# User passes in arg of form <new_id1>-<old_id1>[,count1]:<new_id2>-<old_id2>[,count2]:...
+#  new_id# = the new enum id that was assigned to an error
+#  old_id# = the previous enum id that was assigned to the same error
+#  [,count#] = The number of ids to remap starting at new_id#=old_id# and ending at new_id[#+count#-1]=old_id[#+count#-1]
+#     If not supplied, then ,1 is assumed, which will only update a single id
+def updateRemapDict(remap_string):
+    """Set up global remap_dict based on user input"""
+    remap_list = remap_string.split(":")
+    for rmap in remap_list:
+        count = 1 # Default count if none supplied
+        id_count_list = rmap.split(',')
+        if len(id_count_list) > 1:
+            count = int(id_count_list[1])
+        new_old_id_list = id_count_list[0].split('-')
+        for offset in range(count):
+            remap_dict["%05d" % (int(new_old_id_list[0]) + offset)] = "%05d" % (int(new_old_id_list[1]) + offset)
+    for new_id in sorted(remap_dict):
+        print "Set to remap new id %s to old id %s" % (new_id, remap_dict[new_id])
+
+if __name__ == "__main__":
+    i = 1
+    use_online = True # Attempt to grab spec from online by default
+    update_option = False
+    while (i < len(sys.argv)):
+        arg = sys.argv[i]
+        i = i + 1
+        if (arg == '-spec'):
+            spec_filename = sys.argv[i]
+            # If user specifies local specfile, skip online
+            use_online = False
+            i = i + 1
+        elif (arg == '-out'):
+            out_filename = sys.argv[i]
+            i = i + 1
+        elif (arg == '-gendb'):
+            gen_db = True
+            # Set filename if supplied, else use default
+            if i < len(sys.argv) and not sys.argv[i].startswith('-'):
+                db_filename = sys.argv[i]
+                i = i + 1
+        elif (arg == '-compare'):
+            db_filename = sys.argv[i]
+            spec_compare = True
+            i = i + 1
+        elif (arg == '-update'):
+            update_option = True
+            spec_compare = True
+            gen_db = True
+        elif (arg == '-remap'):
+            updateRemapDict(sys.argv[i])
+            i = i + 1
+        elif (arg in ['-help', '-h']):
+            printHelp()
+            sys.exit()
+    if len(remap_dict) > 1 and not update_option:
+        print "ERROR: '-remap' option can only be used along with '-update' option. Exiting."
+        sys.exit()
+    spec = Specification()
+    spec.loadFile(use_online, spec_filename)
+    #spec.parseTree()
+    #spec.genHeader(out_filename)
+    spec.analyze()
+    if (spec_compare):
+        # Read in old spec info from db file
+        (orig_err_msg_dict, max_id) = spec.readDB(db_filename)
+        # New spec data should already be read into self.val_error_dict
+        updated_dict = spec.compareDB(orig_err_msg_dict, max_id)
+        update_valid = spec.validateUpdateDict(updated_dict)
+        if update_valid:
+            spec.updateDict(updated_dict)
+        else:
+            sys.exit()
+    if (gen_db):
+        spec.genDB(db_filename)
+    print "Writing out file (-out) to '%s'" % (out_filename)
+    spec.genHeader(out_filename)
+
+##### Example dataset
+# <div class="sidebar">
+#   <div class="titlepage">
+#     <div>
+#       <div>
+#         <p class="title">
+#           <strong>Valid Usage</strong> # When we get to this guy, we know we're under interesting sidebar
+#         </p>
+#       </div>
+#     </div>
+#   </div>
+# <div class="itemizedlist">
+#   <ul class="itemizedlist" style="list-style-type: disc; ">
+#     <li class="listitem">
+#       <em class="parameter">
+#         <code>device</code>
+#       </em>
+#       <span class="normative">must</span> be a valid
+#       <code class="code">VkDevice</code> handle
+#     </li>
+#     <li class="listitem">
+#       <em class="parameter">
+#         <code>commandPool</code>
+#       </em>
+#       <span class="normative">must</span> be a valid
+#       <code class="code">VkCommandPool</code> handle
+#     </li>
+#     <li class="listitem">
+#       <em class="parameter">
+#         <code>flags</code>
+#       </em>
+#       <span class="normative">must</span> be a valid combination of
+#       <code class="code">
+#         <a class="link" href="#VkCommandPoolResetFlagBits">VkCommandPoolResetFlagBits</a>
+#       </code> values
+#     </li>
+#     <li class="listitem">
+#       <em class="parameter">
+#         <code>commandPool</code>
+#       </em>
+#       <span class="normative">must</span> have been created, allocated, or retrieved from
+#       <em class="parameter">
+#         <code>device</code>
+#       </em>
+#     </li>
+#     <li class="listitem">All
+#       <code class="code">VkCommandBuffer</code>
+#       objects allocated from
+#       <em class="parameter">
+#         <code>commandPool</code>
+#       </em>
+#       <span class="normative">must</span> not currently be pending execution
+#     </li>
+#   </ul>
+# </div>
+# </div>
+##### Second example dataset
+# <div class="sidebar">
+#   <div class="titlepage">
+#     <div>
+#       <div>
+#         <p class="title">
+#           <strong>Valid Usage</strong>
+#         </p>
+#       </div>
+#     </div>
+#   </div>
+#   <div class="itemizedlist">
+#     <ul class="itemizedlist" style="list-style-type: disc; ">
+#       <li class="listitem">The <em class="parameter"><code>queueFamilyIndex</code></em> member of any given element of <em class="parameter"><code>pQueueCreateInfos</code></em> <span class="normative">must</span> be unique within <em class="parameter"><code>pQueueCreateInfos</code></em>
+#       </li>
+#     </ul>
+#   </div>
+# </div>
+# <div class="sidebar">
+#   <div class="titlepage">
+#     <div>
+#       <div>
+#         <p class="title">
+#           <strong>Valid Usage (Implicit)</strong>
+#         </p>
+#       </div>
+#     </div>
+#   </div>
+#   <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
+#<em class="parameter"><code>sType</code></em> <span class="normative">must</span> be <code class="code">VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO</code>
+#</li><li class="listitem">
+#<em class="parameter"><code>pNext</code></em> <span class="normative">must</span> be <code class="literal">NULL</code>
+#</li><li class="listitem">
+#<em class="parameter"><code>flags</code></em> <span class="normative">must</span> be <code class="literal">0</code>
+#</li><li class="listitem">
+#<em class="parameter"><code>pQueueCreateInfos</code></em> <span class="normative">must</span> be a pointer to an array of <em class="parameter"><code>queueCreateInfoCount</code></em> valid <code class="code">VkDeviceQueueCreateInfo</code> structures
+#</li>
\ No newline at end of file
diff --git a/layers/swapchain.cpp b/layers/swapchain.cpp
index 5aca7f6..f43a472 100644
--- a/layers/swapchain.cpp
+++ b/layers/swapchain.cpp
@@ -382,7 +382,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -433,7 +432,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -519,7 +517,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -606,7 +603,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -691,7 +687,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -778,7 +773,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -1089,7 +1083,6 @@
             // Record the VkSurfaceKHR returned by the ICD:
             my_data->surfaceMap[*pSurface].surface = *pSurface;
             my_data->surfaceMap[*pSurface].pInstance = pInstance;
-            my_data->surfaceMap[*pSurface].usedAllocatorToCreate = (pAllocator != NULL);
             my_data->surfaceMap[*pSurface].numQueueFamilyIndexSupport = 0;
             my_data->surfaceMap[*pSurface].pQueueFamilyIndexSupport = NULL;
             // Point to the associated SwpInstance:
@@ -1151,12 +1144,6 @@
             }
             pSurface->swapchains.clear();
         }
-        if ((pAllocator != NULL) != pSurface->usedAllocatorToCreate) {
-            skip_call |=
-                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT,
-                        reinterpret_cast<uint64_t>(instance), __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
-                        "vkDestroySurfaceKHR() called with incompatible pAllocator from when the object was created.");
-        }
         my_data->surfaceMap.erase(surface);
     }
     lock.unlock();
@@ -1850,29 +1837,6 @@
                              pCreateInfo->clipped);
     }
 
-    // Validate pCreateInfo->oldSwapchain:
-    if (pCreateInfo && pCreateInfo->oldSwapchain) {
-        SwpSwapchain *pOldSwapchain = NULL;
-        {
-            auto it = my_data->swapchainMap.find(pCreateInfo->oldSwapchain);
-            pOldSwapchain = (it == my_data->swapchainMap.end()) ? NULL : &it->second;
-        }
-        if (pOldSwapchain) {
-            if (device != pOldSwapchain->pDevice->device) {
-                skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                            reinterpret_cast<uint64_t>(device), __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
-                            "vkCreateSwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
-            }
-            if (pCreateInfo->surface != pOldSwapchain->pSurface->surface) {
-                skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                            reinterpret_cast<uint64_t>(device), __LINE__, SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE, swapchain_layer_name,
-                            "vkCreateSwapchainKHR() called with pCreateInfo->oldSwapchain pCreateInfo->surface.");
-            }
-        }
-    }
-
     return skip_call;
 }
 
@@ -1903,7 +1867,6 @@
             }
             my_data->swapchainMap[*pSwapchain].pDevice = pDevice;
             my_data->swapchainMap[*pSwapchain].imageCount = 0;
-            my_data->swapchainMap[*pSwapchain].usedAllocatorToCreate = (pAllocator != NULL);
             // Store a pointer to the surface
             SwpPhysicalDevice *pPhysicalDevice = pDevice->pPhysicalDevice;
             SwpInstance *pInstance = (pPhysicalDevice) ? pPhysicalDevice->pInstance : NULL;
@@ -1955,12 +1918,6 @@
         // Delete the SwpSwapchain associated with this swapchain:
         if (pSwapchain->pDevice) {
             pSwapchain->pDevice->swapchains.erase(swapchain);
-            if (device != pSwapchain->pDevice->device) {
-                skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                            reinterpret_cast<uint64_t>(device), __LINE__, SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, swapchain_layer_name,
-                            "vkDestroySwapchainKHR() called with a different VkDevice than the VkSwapchainKHR was created with.");
-            }
         }
         if (pSwapchain->pSurface) {
             pSwapchain->pSurface->swapchains.erase(swapchain);
@@ -1968,12 +1925,6 @@
         if (pSwapchain->imageCount) {
             pSwapchain->images.clear();
         }
-        if ((pAllocator != NULL) != pSwapchain->usedAllocatorToCreate) {
-            skip_call |=
-                log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                        reinterpret_cast<uint64_t>(device), __LINE__, SWAPCHAIN_INCOMPATIBLE_ALLOCATOR, swapchain_layer_name,
-                        "vkDestroySwapchainKHR() called with incompatible pAllocator from when the object was created.");
-        }
         my_data->swapchainMap.erase(swapchain);
     }
     lock.unlock();
@@ -2089,13 +2040,6 @@
                              "vkAcquireNextImageKHR() called even though the %s extension was not enabled for this VkDevice.",
                              VK_KHR_SWAPCHAIN_EXTENSION_NAME);
     }
-    if ((semaphore == VK_NULL_HANDLE) && (fence == VK_NULL_HANDLE)) {
-        skip_call |=
-            log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
-                    reinterpret_cast<uint64_t>(device), __LINE__, SWAPCHAIN_NO_SYNC_FOR_ACQUIRE, swapchain_layer_name,
-                    "vkAcquireNextImageKHR() called with both the semaphore and fence parameters set to VK_NULL_HANDLE (at "
-                    "least one should be used).");
-    }
     SwpSwapchain *pSwapchain = NULL;
     {
         auto it = my_data->swapchainMap.find(swapchain);
@@ -2165,7 +2109,6 @@
 
     std::unique_lock<std::mutex> lock(global_lock);
     for (uint32_t i = 0; pPresentInfo && (i < pPresentInfo->swapchainCount); i++) {
-        uint32_t index = pPresentInfo->pImageIndices[i];
         SwpSwapchain *pSwapchain = NULL;
         {
             auto it = my_data->swapchainMap.find(pPresentInfo->pSwapchains[i]);
@@ -2179,24 +2122,6 @@
                                      "vkQueuePresentKHR() called even though the %s extension was not enabled for this VkDevice.",
                                      VK_KHR_SWAPCHAIN_EXTENSION_NAME);
             }
-            if (index >= pSwapchain->imageCount) {
-                skip_call |=
-                    log_msg(my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
-                            reinterpret_cast<const uint64_t &>(pPresentInfo->pSwapchains[i]), __LINE__, SWAPCHAIN_INDEX_TOO_LARGE,
-                            swapchain_layer_name,
-                            "vkQueuePresentKHR() called for an index that is too large (i.e. %d).  There are only %d images in "
-                            "this VkSwapchainKHR.",
-                            index, pSwapchain->imageCount);
-            } else {
-                if (!pSwapchain->images[index].acquiredByApp) {
-                    skip_call |= log_msg(
-                        my_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT,
-                        reinterpret_cast<const uint64_t &>(pPresentInfo->pSwapchains[i]), __LINE__, SWAPCHAIN_INDEX_NOT_IN_USE,
-                        swapchain_layer_name,
-                        "vkQueuePresentKHR() returned an index (i.e. %d) for an image that is not acquired by the application.",
-                        index);
-                }
-            }
             SwpQueue *pQueue = NULL;
             {
                 auto it = my_data->queueMap.find(queue);
diff --git a/layers/swapchain.h b/layers/swapchain.h
index 9b84f20..8ba39dc 100644
--- a/layers/swapchain.h
+++ b/layers/swapchain.h
@@ -54,26 +54,19 @@
     SWAPCHAIN_CREATE_SWAP_BAD_SHARING_MODE,     // Called vkCreateSwapchainKHR() with a non-supported imageSharingMode
     SWAPCHAIN_CREATE_SWAP_BAD_SHARING_VALUES,   // Called vkCreateSwapchainKHR() with bad values when imageSharingMode is
                                                 // VK_SHARING_MODE_CONCURRENT
-    SWAPCHAIN_CREATE_SWAP_DIFF_SURFACE, // Called vkCreateSwapchainKHR() with pCreateInfo->oldSwapchain that has a different surface
-                                        // than pCreateInfo->surface
-    SWAPCHAIN_DESTROY_SWAP_DIFF_DEVICE, // Called vkDestroySwapchainKHR() with a different VkDevice than vkCreateSwapchainKHR()
     SWAPCHAIN_APP_ACQUIRES_TOO_MANY_IMAGES, // vkAcquireNextImageKHR() asked for more images than are available
-    SWAPCHAIN_INDEX_TOO_LARGE,          // Index is too large for swapchain
-    SWAPCHAIN_INDEX_NOT_IN_USE,         // vkQueuePresentKHR() given index that is not acquired by app
     SWAPCHAIN_BAD_BOOL,                 // VkBool32 that doesn't have value of VK_TRUE or VK_FALSE (e.g. is a non-zero form of true)
     SWAPCHAIN_PRIOR_COUNT,              // Query must be called first to get value of pCount, then called second time
     SWAPCHAIN_INVALID_COUNT,            // Second time a query called, the pCount value didn't match first time
     SWAPCHAIN_WRONG_STYPE,              // The sType for a struct has the wrong value
     SWAPCHAIN_WRONG_NEXT,               // The pNext for a struct is not NULL
     SWAPCHAIN_ZERO_VALUE,               // A value should be non-zero
-    SWAPCHAIN_INCOMPATIBLE_ALLOCATOR,   // pAllocator must be compatible (i.e. NULL or not) when object is created and destroyed
     SWAPCHAIN_DID_NOT_QUERY_QUEUE_FAMILIES,     // A function using a queueFamilyIndex was called before
                                                 // vkGetPhysicalDeviceQueueFamilyProperties() was called
     SWAPCHAIN_QUEUE_FAMILY_INDEX_TOO_LARGE,     // A queueFamilyIndex value is not less than pQueueFamilyPropertyCount returned by
                                                 // vkGetPhysicalDeviceQueueFamilyProperties()
     SWAPCHAIN_SURFACE_NOT_SUPPORTED_WITH_QUEUE, // A surface is not supported by a given queueFamilyIndex, as seen by
                                                 // vkGetPhysicalDeviceSurfaceSupportKHR()
-    SWAPCHAIN_NO_SYNC_FOR_ACQUIRE,      // vkAcquireNextImageKHR should be called with a valid semaphore and/or fence
     SWAPCHAIN_GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY,     // vkGetDisplayPlaneSupportedDisplaysKHR should be called after querying 
                                                         // device display plane properties
     SWAPCHAIN_PLANE_INDEX_TOO_LARGE,    // a planeIndex value is larger than what vkGetDisplayPlaneSupportedDisplaysKHR returns
@@ -153,9 +146,6 @@
     // remembered:
     unordered_map<VkSwapchainKHR, SwpSwapchain *> swapchains;
 
-    // 'true' if pAllocator was non-NULL when vkCreate*SurfaceKHR was called:
-    bool usedAllocatorToCreate;
-
     // Value of pQueueFamilyPropertyCount that was returned by the
     // vkGetPhysicalDeviceQueueFamilyProperties() function:
     uint32_t numQueueFamilyIndexSupport;
@@ -260,9 +250,6 @@
     // remembered:
     uint32_t imageCount;
     unordered_map<int, SwpImage> images;
-
-    // 'true' if pAllocator was non-NULL when vkCreateSwapchainKHR was called:
-    bool usedAllocatorToCreate;
 };
 
 // Create one of these for each VkQueue within a VkDevice:
diff --git a/layers/unique_objects.cpp b/layers/unique_objects.cpp
new file mode 100644
index 0000000..1a79d77
--- /dev/null
+++ b/layers/unique_objects.cpp
@@ -0,0 +1,724 @@
+/*
+ * Copyright (c) 2015-2016 The Khronos Group Inc.
+ * Copyright (c) 2015-2016 Valve Corporation
+ * Copyright (c) 2015-2016 LunarG, Inc.
+ * Copyright (c) 2015-2016 Google, 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: Mark Lobodzinski <mark@lunarg.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unordered_map>
+#include <vector>
+#include <list>
+#include <memory>
+
+#include "vk_loader_platform.h"
+#include "vulkan/vk_layer.h"
+#include "vk_layer_config.h"
+#include "vk_layer_extension_utils.h"
+#include "vk_layer_utils.h"
+#include "vk_layer_table.h"
+#include "vk_layer_logging.h"
+#include "unique_objects.h"
+#include "vk_dispatch_table_helper.h"
+#include "vk_struct_string_helper_cpp.h"
+#include "vk_layer_data.h"
+#include "vk_layer_utils.h"
+
+#include "unique_objects_wrappers.h"
+
+namespace unique_objects {
+
+static void initUniqueObjects(layer_data *instance_data, const VkAllocationCallbacks *pAllocator) {
+    layer_debug_actions(instance_data->report_data, instance_data->logging_callback, pAllocator, "google_unique_objects");
+}
+
+// Handle CreateInstance Extensions
+static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
+    uint32_t i;
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
+    instance_ext_map[disp_table] = {};
+
+    for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].wsi_enabled = true;
+        }
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].display_enabled = true;
+        }
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].xlib_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].xcb_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].wayland_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].mir_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].android_enabled = true;
+        }
+#endif
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
+            instance_ext_map[disp_table].win32_enabled = true;
+        }
+#endif
+
+        // Check for recognized instance extensions
+        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+        if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedInstanceExtensions)) {
+            log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                    0, "UniqueObjects",
+                    "Instance Extension %s is not supported by this layer.  Using this extension may adversely affect "
+                    "validation results and/or produce undefined behavior.",
+                    pCreateInfo->ppEnabledExtensionNames[i]);
+        }
+    }
+}
+
+// Handle CreateDevice Extensions
+static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    VkLayerDispatchTable *disp_table = device_data->device_dispatch_table;
+    PFN_vkGetDeviceProcAddr gpa = disp_table->GetDeviceProcAddr;
+
+    device_data->device_dispatch_table->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
+    disp_table->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
+    disp_table->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
+    disp_table->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
+    disp_table->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
+    device_data->wsi_enabled = false;
+
+    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
+        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
+            device_data->wsi_enabled = true;
+        }
+        // Check for recognized device extensions
+        if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedDeviceExtensions)) {
+            log_msg(device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
+                    0, "UniqueObjects",
+                    "Device Extension %s is not supported by this layer.  Using this extension may adversely affect "
+                    "validation results and/or produce undefined behavior.",
+                    pCreateInfo->ppEnabledExtensionNames[i]);
+        }
+    }
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
+                                              VkInstance *pInstance) {
+    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+    assert(chain_info->u.pLayerInfo);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
+    if (fpCreateInstance == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
+    instance_data->instance = *pInstance;
+    instance_data->instance_dispatch_table = new VkLayerInstanceDispatchTable;
+    layer_init_instance_dispatch_table(*pInstance, instance_data->instance_dispatch_table, fpGetInstanceProcAddr);
+
+    instance_data->instance = *pInstance;
+    instance_data->report_data =
+        debug_report_create_instance(instance_data->instance_dispatch_table, *pInstance, pCreateInfo->enabledExtensionCount,
+                                     pCreateInfo->ppEnabledExtensionNames);
+
+    // Set up temporary debug callbacks to output messages at CreateInstance-time
+    if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &instance_data->num_tmp_callbacks, &instance_data->tmp_dbg_create_infos,
+                                  &instance_data->tmp_callbacks)) {
+        if (instance_data->num_tmp_callbacks > 0) {
+            if (layer_enable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks,
+                                           instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks)) {
+                layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
+                instance_data->num_tmp_callbacks = 0;
+            }
+        }
+    }
+
+    initUniqueObjects(instance_data, pAllocator);
+    checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
+
+    // Disable and free tmp callbacks, no longer necessary
+    if (instance_data->num_tmp_callbacks > 0) {
+        layer_disable_tmp_callbacks(instance_data->report_data, instance_data->num_tmp_callbacks, instance_data->tmp_callbacks);
+        layer_free_tmp_callbacks(instance_data->tmp_dbg_create_infos, instance_data->tmp_callbacks);
+        instance_data->num_tmp_callbacks = 0;
+    }
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
+    dispatch_key key = get_dispatch_key(instance);
+    layer_data *instance_data = get_my_data_ptr(key, layer_data_map);
+    VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
+    instance_ext_map.erase(disp_table);
+    disp_table->DestroyInstance(instance, pAllocator);
+
+    // Clean up logging callback, if any
+    while (instance_data->logging_callback.size() > 0) {
+        VkDebugReportCallbackEXT callback = instance_data->logging_callback.back();
+        layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+        instance_data->logging_callback.pop_back();
+    }
+
+    layer_debug_report_destroy_instance(instance_data->report_data);
+    layer_data_map.erase(key);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo,
+                                            const VkAllocationCallbacks *pAllocator, VkDevice *pDevice) {
+    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
+    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
+
+    assert(chain_info->u.pLayerInfo);
+    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
+    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
+    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
+    if (fpCreateDevice == NULL) {
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+
+    // Advance the link info for the next element on the chain
+    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
+
+    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
+    if (result != VK_SUCCESS) {
+        return result;
+    }
+
+    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
+    my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
+
+    // Setup layer's device dispatch table
+    my_device_data->device_dispatch_table = new VkLayerDispatchTable;
+    layer_init_device_dispatch_table(*pDevice, my_device_data->device_dispatch_table, fpGetDeviceProcAddr);
+
+    createDeviceRegisterExtensions(pCreateInfo, *pDevice);
+    // Set gpu for this device in order to get at any objects mapped at instance level
+
+    my_device_data->gpu = gpu;
+
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
+    dispatch_key key = get_dispatch_key(device);
+    layer_data *dev_data = get_my_data_ptr(key, layer_data_map);
+
+    layer_debug_report_destroy_device(device);
+    dev_data->device_dispatch_table->DestroyDevice(device, pAllocator);
+    layer_data_map.erase(key);
+}
+
+static const VkLayerProperties globalLayerProps = {"VK_LAYER_GOOGLE_unique_objects",
+                                                   VK_LAYER_API_VERSION, // specVersion
+                                                   1,                    // implementationVersion
+                                                   "Google Validation Layer"};
+
+static inline PFN_vkVoidFunction layer_intercept_proc(const char *name) {
+    for (int i = 0; i < sizeof(procmap) / sizeof(procmap[0]); i++) {
+        if (!strcmp(name, procmap[i].name))
+            return procmap[i].pFunc;
+    }
+    return NULL;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount, VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                              VkLayerProperties *pProperties) {
+    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                    VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
+        return util_GetExtensionProperties(0, NULL, pCount, pProperties);
+
+    return VK_ERROR_LAYER_NOT_PRESENT;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice, const char *pLayerName,
+                                                                  uint32_t *pCount, VkExtensionProperties *pProperties) {
+    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))
+        return util_GetExtensionProperties(0, nullptr, pCount, pProperties);
+
+    assert(physicalDevice);
+
+    dispatch_key key = get_dispatch_key(physicalDevice);
+    layer_data *instance_data = get_my_data_ptr(key, layer_data_map);
+    return instance_data->instance_dispatch_table->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char *funcName) {
+    PFN_vkVoidFunction addr;
+    assert(device);
+    addr = layer_intercept_proc(funcName);
+    if (addr) {
+        return addr;
+    }
+
+    layer_data *dev_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    VkLayerDispatchTable *disp_table = dev_data->device_dispatch_table;
+    if (disp_table->GetDeviceProcAddr == NULL) {
+        return NULL;
+    }
+    return disp_table->GetDeviceProcAddr(device, funcName);
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char *funcName) {
+    PFN_vkVoidFunction addr;
+
+    addr = layer_intercept_proc(funcName);
+    if (addr) {
+        return addr;
+    }
+    assert(instance);
+
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    addr = debug_report_get_instance_proc_addr(instance_data->report_data, funcName);
+    if (addr) {
+        return addr;
+    }
+
+    VkLayerInstanceDispatchTable *disp_table = instance_data->instance_dispatch_table;
+    if (disp_table->GetInstanceProcAddr == NULL) {
+        return NULL;
+    }
+    return disp_table->GetInstanceProcAddr(instance, funcName);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
+                                              const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
+    const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
+    std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
+    std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
+    layer_data *device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+
+    if ((pAllocateInfo != nullptr) &&
+        ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
+        // Assuming there is only one extension struct of this type in the list for now
+        safe_dedicated_allocate_info =
+            std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
+        safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo(pAllocateInfo));
+        input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
+
+        const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
+        GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
+        while (orig_pnext != nullptr) {
+            if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
+                safe_dedicated_allocate_info->initialize(
+                    reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
+
+                std::unique_lock<std::mutex> lock(global_lock);
+
+                if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
+                    uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
+                    safe_dedicated_allocate_info->buffer =
+                        reinterpret_cast<VkBuffer &>(device_data->unique_id_mapping[local_buffer]);
+                }
+
+                if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
+                    uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
+                    safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(device_data->unique_id_mapping[local_image]);
+                }
+
+                lock.unlock();
+
+                input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
+                input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
+            } else {
+                // TODO: generic handling of pNext copies
+            }
+
+            orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
+        }
+    }
+
+    VkResult result = device_data->device_dispatch_table->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
+
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        uint64_t unique_id = global_unique_id++;
+        device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
+        *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
+    }
+
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                      const VkComputePipelineCreateInfo *pCreateInfos,
+                                                      const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
+    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
+    if (pCreateInfos) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
+        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
+            local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
+            if (pCreateInfos[idx0].basePipelineHandle) {
+                local_pCreateInfos[idx0].basePipelineHandle =
+                    (VkPipeline)my_device_data
+                        ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
+            }
+            if (pCreateInfos[idx0].layout) {
+                local_pCreateInfos[idx0].layout =
+                    (VkPipelineLayout)
+                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
+            }
+            if (pCreateInfos[idx0].stage.module) {
+                local_pCreateInfos[idx0].stage.module =
+                    (VkShaderModule)
+                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].stage.module)];
+            }
+        }
+    }
+    if (pipelineCache) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
+    }
+
+    VkResult result = my_device_data->device_dispatch_table->CreateComputePipelines(
+        device, pipelineCache, createInfoCount, (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
+    delete[] local_pCreateInfos;
+    if (VK_SUCCESS == result) {
+        uint64_t unique_id = 0;
+        std::lock_guard<std::mutex> lock(global_lock);
+        for (uint32_t i = 0; i < createInfoCount; ++i) {
+            unique_id = global_unique_id++;
+            my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
+            pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
+                                                       const VkGraphicsPipelineCreateInfo *pCreateInfos,
+                                                       const VkAllocationCallbacks *pAllocator, VkPipeline *pPipelines) {
+    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = NULL;
+    if (pCreateInfos) {
+        local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
+        std::lock_guard<std::mutex> lock(global_lock);
+        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
+            local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
+            if (pCreateInfos[idx0].basePipelineHandle) {
+                local_pCreateInfos[idx0].basePipelineHandle =
+                    (VkPipeline)my_device_data
+                        ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
+            }
+            if (pCreateInfos[idx0].layout) {
+                local_pCreateInfos[idx0].layout =
+                    (VkPipelineLayout)
+                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
+            }
+            if (pCreateInfos[idx0].pStages) {
+                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
+                    if (pCreateInfos[idx0].pStages[idx1].module) {
+                        local_pCreateInfos[idx0].pStages[idx1].module =
+                            (VkShaderModule)my_device_data
+                                ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].pStages[idx1].module)];
+                    }
+                }
+            }
+            if (pCreateInfos[idx0].renderPass) {
+                local_pCreateInfos[idx0].renderPass =
+                    (VkRenderPass)
+                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].renderPass)];
+            }
+        }
+    }
+    if (pipelineCache) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
+    }
+
+    VkResult result = my_device_data->device_dispatch_table->CreateGraphicsPipelines(
+        device, pipelineCache, createInfoCount, (const VkGraphicsPipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
+    delete[] local_pCreateInfos;
+    if (VK_SUCCESS == result) {
+        uint64_t unique_id = 0;
+        std::lock_guard<std::mutex> lock(global_lock);
+        for (uint32_t i = 0; i < createInfoCount; ++i) {
+            unique_id = global_unique_id++;
+            my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
+            pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(VkInstance instance,
+                                                            const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                            const VkAllocationCallbacks *pAllocator,
+                                                            VkDebugReportCallbackEXT *pMsgCallback) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    VkResult result =
+        instance_data->instance_dispatch_table->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
+
+    if (VK_SUCCESS == result) {
+        result = layer_create_msg_callback(instance_data->report_data, false, pCreateInfo, pAllocator, pMsgCallback);
+    }
+    return result;
+}
+
+VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT callback,
+                                                         const VkAllocationCallbacks *pAllocator) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    instance_data->instance_dispatch_table->DestroyDebugReportCallbackEXT(instance, callback, pAllocator);
+    layer_destroy_msg_callback(instance_data->report_data, callback, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                 VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                 int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+    layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
+    instance_data->instance_dispatch_table->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix,
+                                                                  pMsg);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+                                                  const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
+    if (pCreateInfo) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
+        local_pCreateInfo->oldSwapchain =
+            (VkSwapchainKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->oldSwapchain)];
+        // Need to pull surface mapping from the instance-level map
+        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(my_map_data->gpu), layer_data_map);
+        local_pCreateInfo->surface =
+            (VkSurfaceKHR)instance_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->surface)];
+    }
+
+    VkResult result = my_map_data->device_dispatch_table->CreateSwapchainKHR(
+        device, (const VkSwapchainCreateInfoKHR *)local_pCreateInfo, pAllocator, pSwapchain);
+    if (local_pCreateInfo) {
+        delete local_pCreateInfo;
+    }
+    if (VK_SUCCESS == result) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        uint64_t unique_id = global_unique_id++;
+        my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pSwapchain);
+        *pSwapchain = reinterpret_cast<VkSwapchainKHR &>(unique_id);
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
+                                                     VkImage *pSwapchainImages) {
+    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
+    if (VK_NULL_HANDLE != swapchain) {
+        std::lock_guard<std::mutex> lock(global_lock);
+        swapchain = (VkSwapchainKHR)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(swapchain)];
+    }
+    VkResult result =
+        my_device_data->device_dispatch_table->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
+    // TODO : Need to add corresponding code to delete these images
+    if (VK_SUCCESS == result) {
+        if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
+            uint64_t unique_id = 0;
+            std::lock_guard<std::mutex> lock(global_lock);
+            for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
+                unique_id = global_unique_id++;
+                my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pSwapchainImages[i]);
+                pSwapchainImages[i] = reinterpret_cast<VkImage &>(unique_id);
+            }
+        }
+    }
+    return result;
+}
+
+#ifndef __ANDROID__
+VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t *pPropertyCount,
+                                                                     VkDisplayPropertiesKHR *pProperties) {
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    safe_VkDisplayPropertiesKHR *local_pProperties = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        if (pProperties) {
+            local_pProperties = new safe_VkDisplayPropertiesKHR[*pPropertyCount];
+            for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
+                local_pProperties[idx0].initialize(&pProperties[idx0]);
+                if (pProperties[idx0].display) {
+                    local_pProperties[idx0].display =
+                        (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pProperties[idx0].display)];
+                }
+            }
+        }
+    }
+
+    VkResult result = my_map_data->instance_dispatch_table->GetPhysicalDeviceDisplayPropertiesKHR(
+        physicalDevice, pPropertyCount, (VkDisplayPropertiesKHR *)local_pProperties);
+    if (result == VK_SUCCESS && pProperties) {
+        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
+            std::lock_guard<std::mutex> lock(global_lock);
+
+            uint64_t unique_id = global_unique_id++;
+            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].display);
+            pProperties[idx0].display = reinterpret_cast<VkDisplayKHR &>(unique_id);
+            pProperties[idx0].displayName = local_pProperties[idx0].displayName;
+            pProperties[idx0].physicalDimensions = local_pProperties[idx0].physicalDimensions;
+            pProperties[idx0].physicalResolution = local_pProperties[idx0].physicalResolution;
+            pProperties[idx0].supportedTransforms = local_pProperties[idx0].supportedTransforms;
+            pProperties[idx0].planeReorderPossible = local_pProperties[idx0].planeReorderPossible;
+            pProperties[idx0].persistentContent = local_pProperties[idx0].persistentContent;
+        }
+    }
+    if (local_pProperties) {
+        delete[] local_pProperties;
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+                                                                   uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    VkResult result = my_map_data->instance_dispatch_table->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex,
+                                                                                                pDisplayCount, pDisplays);
+    if (VK_SUCCESS == result) {
+        if ((*pDisplayCount > 0) && pDisplays) {
+            std::lock_guard<std::mutex> lock(global_lock);
+            for (uint32_t i = 0; i < *pDisplayCount; i++) {
+                auto it = my_map_data->unique_id_mapping.find(reinterpret_cast<const uint64_t &>(pDisplays[i]));
+                assert(it != my_map_data->unique_id_mapping.end());
+                pDisplays[i] = reinterpret_cast<VkDisplayKHR &>(it->second);
+            }
+        }
+    }
+    return result;
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+                                                           uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
+    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
+    safe_VkDisplayModePropertiesKHR *local_pProperties = NULL;
+    {
+        std::lock_guard<std::mutex> lock(global_lock);
+        display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(display)];
+        if (pProperties) {
+            local_pProperties = new safe_VkDisplayModePropertiesKHR[*pPropertyCount];
+            for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
+                local_pProperties[idx0].initialize(&pProperties[idx0]);
+            }
+        }
+    }
+
+    VkResult result = my_map_data->instance_dispatch_table->GetDisplayModePropertiesKHR(
+        physicalDevice, display, pPropertyCount, (VkDisplayModePropertiesKHR *)local_pProperties);
+    if (result == VK_SUCCESS && pProperties) {
+        for (uint32_t idx0 = 0; idx0 < *pPropertyCount; ++idx0) {
+            std::lock_guard<std::mutex> lock(global_lock);
+
+            uint64_t unique_id = global_unique_id++;
+            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].displayMode);
+            pProperties[idx0].displayMode = reinterpret_cast<VkDisplayModeKHR &>(unique_id);
+            pProperties[idx0].parameters.visibleRegion.width = local_pProperties[idx0].parameters.visibleRegion.width;
+            pProperties[idx0].parameters.visibleRegion.height = local_pProperties[idx0].parameters.visibleRegion.height;
+            pProperties[idx0].parameters.refreshRate = local_pProperties[idx0].parameters.refreshRate;
+        }
+    }
+    if (local_pProperties) {
+        delete[] local_pProperties;
+    }
+    return result;
+}
+#endif
+
+} // namespace unique_objects
+
+// vk_layer_logging.h expects these to be defined
+VKAPI_ATTR VkResult VKAPI_CALL vkCreateDebugReportCallbackEXT(VkInstance instance,
+                                                              const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
+                                                              const VkAllocationCallbacks *pAllocator,
+                                                              VkDebugReportCallbackEXT *pMsgCallback) {
+    return unique_objects::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback,
+                                                           const VkAllocationCallbacks *pAllocator) {
+    unique_objects::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);
+}
+
+VKAPI_ATTR void VKAPI_CALL vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags,
+                                                   VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location,
+                                                   int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {
+    unique_objects::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,
+                                                                                      VkExtensionProperties *pProperties) {
+    return unique_objects::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,
+                                                                                  VkLayerProperties *pProperties) {
+    return unique_objects::EnumerateInstanceLayerProperties(pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount,
+                                                                                VkLayerProperties *pProperties) {
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return unique_objects::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName) {
+    return unique_objects::GetDeviceProcAddr(dev, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName) {
+    return unique_objects::GetInstanceProcAddr(instance, funcName);
+}
+
+VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+                                                                                    const char *pLayerName, uint32_t *pCount,
+                                                                                    VkExtensionProperties *pProperties) {
+    assert(physicalDevice == VK_NULL_HANDLE);
+    return unique_objects::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
+}
diff --git a/layers/unique_objects.h b/layers/unique_objects.h
index ead78a4..a0fe99e 100644
--- a/layers/unique_objects.h
+++ b/layers/unique_objects.h
@@ -16,29 +16,17 @@
  * limitations under the License.
  *
  * Author: Tobin Ehlis <tobine@google.com>
+ * Author: Mark Lobodzinski <mark@lunarg.com>
  */
 
-#include "vk_loader_platform.h"
 #include "vulkan/vulkan.h"
 
-#include <cinttypes>
-#include <memory>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <unordered_map>
-#include <vector>
-#include <mutex>
-
-#include "vulkan/vk_layer.h"
-#include "vk_layer_config.h"
-#include "vk_layer_table.h"
 #include "vk_layer_data.h"
-#include "vk_layer_logging.h"
-#include "vk_layer_extension_utils.h"
 #include "vk_safe_struct.h"
 #include "vk_layer_utils.h"
+#include "mutex"
+
+#pragma once
 
 namespace unique_objects {
 
@@ -65,7 +53,9 @@
     VK_EXT_DEBUG_MARKER_EXTENSION_NAME
     VK_EXT_DEBUG_REPORT_EXTENSION_NAME
     VK_KHR_DISPLAY_EXTENSION_NAME
-    VK_KHR_SURFACE_EXTENSION_NAME;
+    VK_KHR_SURFACE_EXTENSION_NAME
+    VK_NV_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
+    VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME;
 
 static const char *kUniqueObjectsSupportedDeviceExtensions =
     VK_AMD_RASTERIZATION_ORDER_EXTENSION_NAME
@@ -78,7 +68,17 @@
     VK_KHR_SWAPCHAIN_EXTENSION_NAME
     VK_KHR_DISPLAY_SWAPCHAIN_EXTENSION_NAME
     VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME
-    VK_NV_GLSL_SHADER_EXTENSION_NAME;
+    VK_NV_GLSL_SHADER_EXTENSION_NAME
+    VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME
+    VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME
+    VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME
+    VK_AMD_SHADER_BALLOT_EXTENSION_NAME
+    VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+    VK_NV_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME
+    VK_NV_WIN32_KEYED_MUTEX_EXTENSION_NAME
+#endif
+    VK_NV_EXTERNAL_MEMORY_EXTENSION_NAME;
 
 // All increments must be guarded by global_lock
 static uint64_t global_unique_id = 1;
@@ -88,6 +88,8 @@
 
     debug_report_data *report_data;
     std::vector<VkDebugReportCallbackEXT> logging_callback;
+    VkLayerDispatchTable *device_dispatch_table;
+    VkLayerInstanceDispatchTable *instance_dispatch_table;
 
     // The following are for keeping track of the temporary callbacks that can
     // be used in vkCreateInstance and vkDestroyInstance:
@@ -113,10 +115,9 @@
     bool display_enabled;
 };
 
-static std::unordered_map<void *, struct instance_extension_enables> instanceExtMap;
+static std::unordered_map<void *, struct instance_extension_enables> instance_ext_map;
 static std::unordered_map<void *, layer_data *> layer_data_map;
-static device_table_map unique_objects_device_table_map;
-static instance_table_map unique_objects_instance_table_map;
+
 static std::mutex global_lock; // Protect map accesses and unique_id increments
 
 struct GenericHeader {
@@ -140,526 +141,4 @@
     return false;
 }
 
-static void init_unique_objects(layer_data *my_data, const VkAllocationCallbacks *pAllocator) {
-    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "google_unique_objects");
-}
-
-// Handle CreateInstance
-static void checkInstanceRegisterExtensions(const VkInstanceCreateInfo *pCreateInfo, VkInstance instance) {
-    uint32_t i;
-    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
-
-    instanceExtMap[pDisp] = {};
-
-    for (i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].wsi_enabled = true;
-        }
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_DISPLAY_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].display_enabled = true;
-        }
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XLIB_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].xlib_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_XCB_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_XCB_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].xcb_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].wayland_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_MIR_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_MIR_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].mir_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_ANDROID_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].android_enabled = true;
-        }
-#endif
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_WIN32_SURFACE_EXTENSION_NAME) == 0) {
-            instanceExtMap[pDisp].win32_enabled = true;
-        }
-#endif
-
-        // Check for recognized instance extensions
-        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);
-        if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedInstanceExtensions)) {
-            log_msg(instance_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__,
-                    0, "UniqueObjects",
-                    "Instance Extension %s is not supported by this layer.  Using this extension may adversely affect "
-                    "validation results and/or produce undefined behavior.",
-                    pCreateInfo->ppEnabledExtensionNames[i]);
-        }
-    }
-}
-
-VkResult explicit_CreateInstance(const VkInstanceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                                 VkInstance *pInstance) {
-    VkLayerInstanceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkCreateInstance fpCreateInstance = (PFN_vkCreateInstance)fpGetInstanceProcAddr(NULL, "vkCreateInstance");
-    if (fpCreateInstance == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_data = get_my_data_ptr(get_dispatch_key(*pInstance), layer_data_map);
-    my_data->instance = *pInstance;
-    VkLayerInstanceDispatchTable *pTable = initInstanceTable(*pInstance, fpGetInstanceProcAddr, unique_objects_instance_table_map);
-
-    my_data->instance = *pInstance;
-    my_data->report_data = debug_report_create_instance(pTable, *pInstance, pCreateInfo->enabledExtensionCount,
-        pCreateInfo->ppEnabledExtensionNames);
-
-    // Set up temporary debug callbacks to output messages at CreateInstance-time
-    if (!layer_copy_tmp_callbacks(pCreateInfo->pNext, &my_data->num_tmp_callbacks, &my_data->tmp_dbg_create_infos,
-                                  &my_data->tmp_callbacks)) {
-        if (my_data->num_tmp_callbacks > 0) {
-            if (layer_enable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_dbg_create_infos,
-                                           my_data->tmp_callbacks)) {
-                layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks);
-                my_data->num_tmp_callbacks = 0;
-            }
-        }
-    }
-
-    init_unique_objects(my_data, pAllocator);
-    checkInstanceRegisterExtensions(pCreateInfo, *pInstance);
-
-    // Disable and free tmp callbacks, no longer necessary
-    if (my_data->num_tmp_callbacks > 0) {
-        layer_disable_tmp_callbacks(my_data->report_data, my_data->num_tmp_callbacks, my_data->tmp_callbacks);
-        layer_free_tmp_callbacks(my_data->tmp_dbg_create_infos, my_data->tmp_callbacks);
-        my_data->num_tmp_callbacks = 0;
-    }
-
-    return result;
-}
-
-void explicit_DestroyInstance(VkInstance instance, const VkAllocationCallbacks *pAllocator) {
-    dispatch_key key = get_dispatch_key(instance);
-    layer_data *my_data = get_my_data_ptr(key, layer_data_map);
-    VkLayerInstanceDispatchTable *pDisp = get_dispatch_table(unique_objects_instance_table_map, instance);
-    instanceExtMap.erase(pDisp);
-    pDisp->DestroyInstance(instance, pAllocator);
-
-    // Clean up logging callback, if any
-    while (my_data->logging_callback.size() > 0) {
-        VkDebugReportCallbackEXT callback = my_data->logging_callback.back();
-        layer_destroy_msg_callback(my_data->report_data, callback, pAllocator);
-        my_data->logging_callback.pop_back();
-    }
-
-    layer_debug_report_destroy_instance(my_data->report_data);
-    layer_data_map.erase(key);
-}
-
-// Handle CreateDevice
-static void createDeviceRegisterExtensions(const VkDeviceCreateInfo *pCreateInfo, VkDevice device) {
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    VkLayerDispatchTable *pDisp = get_dispatch_table(unique_objects_device_table_map, device);
-    PFN_vkGetDeviceProcAddr gpa = pDisp->GetDeviceProcAddr;
-    pDisp->CreateSwapchainKHR = (PFN_vkCreateSwapchainKHR)gpa(device, "vkCreateSwapchainKHR");
-    pDisp->DestroySwapchainKHR = (PFN_vkDestroySwapchainKHR)gpa(device, "vkDestroySwapchainKHR");
-    pDisp->GetSwapchainImagesKHR = (PFN_vkGetSwapchainImagesKHR)gpa(device, "vkGetSwapchainImagesKHR");
-    pDisp->AcquireNextImageKHR = (PFN_vkAcquireNextImageKHR)gpa(device, "vkAcquireNextImageKHR");
-    pDisp->QueuePresentKHR = (PFN_vkQueuePresentKHR)gpa(device, "vkQueuePresentKHR");
-    my_device_data->wsi_enabled = false;
-
-    for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
-        if (strcmp(pCreateInfo->ppEnabledExtensionNames[i], VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
-            my_device_data->wsi_enabled = true;
-        }
-        // Check for recognized device extensions
-        if (!white_list(pCreateInfo->ppEnabledExtensionNames[i], kUniqueObjectsSupportedDeviceExtensions)) {
-            log_msg(my_device_data->report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
-                    __LINE__, 0, "UniqueObjects",
-                    "Device Extension %s is not supported by this layer.  Using this extension may adversely affect "
-                    "validation results and/or produce undefined behavior.",
-                    pCreateInfo->ppEnabledExtensionNames[i]);
-        }
-    }
-}
-
-VkResult explicit_CreateDevice(VkPhysicalDevice gpu, const VkDeviceCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
-                               VkDevice *pDevice) {
-    layer_data *my_instance_data = get_my_data_ptr(get_dispatch_key(gpu), layer_data_map);
-    VkLayerDeviceCreateInfo *chain_info = get_chain_info(pCreateInfo, VK_LAYER_LINK_INFO);
-
-    assert(chain_info->u.pLayerInfo);
-    PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = chain_info->u.pLayerInfo->pfnNextGetInstanceProcAddr;
-    PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = chain_info->u.pLayerInfo->pfnNextGetDeviceProcAddr;
-    PFN_vkCreateDevice fpCreateDevice = (PFN_vkCreateDevice)fpGetInstanceProcAddr(my_instance_data->instance, "vkCreateDevice");
-    if (fpCreateDevice == NULL) {
-        return VK_ERROR_INITIALIZATION_FAILED;
-    }
-
-    // Advance the link info for the next element on the chain
-    chain_info->u.pLayerInfo = chain_info->u.pLayerInfo->pNext;
-
-    VkResult result = fpCreateDevice(gpu, pCreateInfo, pAllocator, pDevice);
-    if (result != VK_SUCCESS) {
-        return result;
-    }
-
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(*pDevice), layer_data_map);
-    my_device_data->report_data = layer_debug_report_create_device(my_instance_data->report_data, *pDevice);
-
-    // Setup layer's device dispatch table
-    initDeviceTable(*pDevice, fpGetDeviceProcAddr, unique_objects_device_table_map);
-
-    createDeviceRegisterExtensions(pCreateInfo, *pDevice);
-    // Set gpu for this device in order to get at any objects mapped at instance level
-
-    my_device_data->gpu = gpu;
-
-    return result;
-}
-
-void explicit_DestroyDevice(VkDevice device, const VkAllocationCallbacks *pAllocator) {
-    dispatch_key key = get_dispatch_key(device);
-    layer_debug_report_destroy_device(device);
-    get_dispatch_table(unique_objects_device_table_map, device)->DestroyDevice(device, pAllocator);
-    layer_data_map.erase(key);
-}
-
-VkResult explicit_AllocateMemory(VkDevice device, const VkMemoryAllocateInfo *pAllocateInfo,
-                                 const VkAllocationCallbacks *pAllocator, VkDeviceMemory *pMemory) {
-    const VkMemoryAllocateInfo *input_allocate_info = pAllocateInfo;
-    std::unique_ptr<safe_VkMemoryAllocateInfo> safe_allocate_info;
-    std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV> safe_dedicated_allocate_info;
-    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
-    if ((pAllocateInfo != nullptr) &&
-        ContainsExtStruct(pAllocateInfo, VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV)) {
-        // Assuming there is only one extension struct of this type in the list for now
-        safe_dedicated_allocate_info =
-            std::unique_ptr<safe_VkDedicatedAllocationMemoryAllocateInfoNV>(new safe_VkDedicatedAllocationMemoryAllocateInfoNV);
-        safe_allocate_info = std::unique_ptr<safe_VkMemoryAllocateInfo>(new safe_VkMemoryAllocateInfo);
-
-        safe_allocate_info->initialize(pAllocateInfo);
-        input_allocate_info = reinterpret_cast<const VkMemoryAllocateInfo *>(safe_allocate_info.get());
-
-        const GenericHeader *orig_pnext = reinterpret_cast<const GenericHeader *>(pAllocateInfo->pNext);
-        GenericHeader *input_pnext = reinterpret_cast<GenericHeader *>(safe_allocate_info.get());
-        while (orig_pnext != nullptr) {
-            if (orig_pnext->sType == VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV) {
-                safe_dedicated_allocate_info->initialize(
-                    reinterpret_cast<const VkDedicatedAllocationMemoryAllocateInfoNV *>(orig_pnext));
-
-                std::unique_lock<std::mutex> lock(global_lock);
-
-                if (safe_dedicated_allocate_info->buffer != VK_NULL_HANDLE) {
-                    uint64_t local_buffer = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->buffer);
-                    safe_dedicated_allocate_info->buffer =
-                        reinterpret_cast<VkBuffer &>(my_map_data->unique_id_mapping[local_buffer]);
-                }
-
-                if (safe_dedicated_allocate_info->image != VK_NULL_HANDLE) {
-                    uint64_t local_image = reinterpret_cast<uint64_t &>(safe_dedicated_allocate_info->image);
-                    safe_dedicated_allocate_info->image = reinterpret_cast<VkImage &>(my_map_data->unique_id_mapping[local_image]);
-                }
-
-                lock.unlock();
-
-                input_pnext->pNext = reinterpret_cast<GenericHeader *>(safe_dedicated_allocate_info.get());
-                input_pnext = reinterpret_cast<GenericHeader *>(input_pnext->pNext);
-            } else {
-                // TODO: generic handling of pNext copies
-            }
-
-            orig_pnext = reinterpret_cast<const GenericHeader *>(orig_pnext->pNext);
-        }
-    }
-
-    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
-                          ->AllocateMemory(device, input_allocate_info, pAllocator, pMemory);
-
-    if (VK_SUCCESS == result) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        uint64_t unique_id = global_unique_id++;
-        my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pMemory);
-        *pMemory = reinterpret_cast<VkDeviceMemory &>(unique_id);
-    }
-
-    return result;
-}
-
-VkResult explicit_CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                         const VkComputePipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                         VkPipeline *pPipelines) {
-    // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'stage': {'module': 'VkShaderModule'},
-    // 'layout': 'VkPipelineLayout', 'basePipelineHandle': 'VkPipeline'}}
-    // LOCAL DECLS:{'pCreateInfos': 'VkComputePipelineCreateInfo*'}
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    safe_VkComputePipelineCreateInfo *local_pCreateInfos = NULL;
-    if (pCreateInfos) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        local_pCreateInfos = new safe_VkComputePipelineCreateInfo[createInfoCount];
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                local_pCreateInfos[idx0].basePipelineHandle =
-                    (VkPipeline)my_device_data
-                        ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
-            }
-            if (pCreateInfos[idx0].layout) {
-                local_pCreateInfos[idx0].layout =
-                    (VkPipelineLayout)
-                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
-            }
-            if (pCreateInfos[idx0].stage.module) {
-                local_pCreateInfos[idx0].stage.module =
-                    (VkShaderModule)
-                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].stage.module)];
-            }
-        }
-    }
-    if (pipelineCache) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
-    }
-
-    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
-                          ->CreateComputePipelines(device, pipelineCache, createInfoCount,
-                                                   (const VkComputePipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
-    delete[] local_pCreateInfos;
-    if (VK_SUCCESS == result) {
-        uint64_t unique_id = 0;
-        std::lock_guard<std::mutex> lock(global_lock);
-        for (uint32_t i = 0; i < createInfoCount; ++i) {
-            unique_id = global_unique_id++;
-            my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
-            pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
-        }
-    }
-    return result;
-}
-
-VkResult explicit_CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount,
-                                          const VkGraphicsPipelineCreateInfo *pCreateInfos, const VkAllocationCallbacks *pAllocator,
-                                          VkPipeline *pPipelines) {
-    // STRUCT USES:{'pipelineCache': 'VkPipelineCache', 'pCreateInfos[createInfoCount]': {'layout': 'VkPipelineLayout',
-    // 'pStages[stageCount]': {'module': 'VkShaderModule'}, 'renderPass': 'VkRenderPass', 'basePipelineHandle': 'VkPipeline'}}
-    // LOCAL DECLS:{'pCreateInfos': 'VkGraphicsPipelineCreateInfo*'}
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    safe_VkGraphicsPipelineCreateInfo *local_pCreateInfos = NULL;
-    if (pCreateInfos) {
-        local_pCreateInfos = new safe_VkGraphicsPipelineCreateInfo[createInfoCount];
-        std::lock_guard<std::mutex> lock(global_lock);
-        for (uint32_t idx0 = 0; idx0 < createInfoCount; ++idx0) {
-            local_pCreateInfos[idx0].initialize(&pCreateInfos[idx0]);
-            if (pCreateInfos[idx0].basePipelineHandle) {
-                local_pCreateInfos[idx0].basePipelineHandle =
-                    (VkPipeline)my_device_data
-                        ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].basePipelineHandle)];
-            }
-            if (pCreateInfos[idx0].layout) {
-                local_pCreateInfos[idx0].layout =
-                    (VkPipelineLayout)
-                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].layout)];
-            }
-            if (pCreateInfos[idx0].pStages) {
-                for (uint32_t idx1 = 0; idx1 < pCreateInfos[idx0].stageCount; ++idx1) {
-                    if (pCreateInfos[idx0].pStages[idx1].module) {
-                        local_pCreateInfos[idx0].pStages[idx1].module =
-                            (VkShaderModule)my_device_data
-                                ->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].pStages[idx1].module)];
-                    }
-                }
-            }
-            if (pCreateInfos[idx0].renderPass) {
-                local_pCreateInfos[idx0].renderPass =
-                    (VkRenderPass)
-                        my_device_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfos[idx0].renderPass)];
-            }
-        }
-    }
-    if (pipelineCache) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        pipelineCache = (VkPipelineCache)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(pipelineCache)];
-    }
-
-    VkResult result =
-        get_dispatch_table(unique_objects_device_table_map, device)
-            ->CreateGraphicsPipelines(device, pipelineCache, createInfoCount,
-                                      (const VkGraphicsPipelineCreateInfo *)local_pCreateInfos, pAllocator, pPipelines);
-    delete[] local_pCreateInfos;
-    if (VK_SUCCESS == result) {
-        uint64_t unique_id = 0;
-        std::lock_guard<std::mutex> lock(global_lock);
-        for (uint32_t i = 0; i < createInfoCount; ++i) {
-            unique_id = global_unique_id++;
-            my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pPipelines[i]);
-            pPipelines[i] = reinterpret_cast<VkPipeline &>(unique_id);
-        }
-    }
-    return result;
-}
-
-VkResult explicit_CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
-                                     const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
-    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-
-    safe_VkSwapchainCreateInfoKHR *local_pCreateInfo = NULL;
-    if (pCreateInfo) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        local_pCreateInfo = new safe_VkSwapchainCreateInfoKHR(pCreateInfo);
-        local_pCreateInfo->oldSwapchain =
-            (VkSwapchainKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->oldSwapchain)];
-        // Need to pull surface mapping from the instance-level map
-        layer_data *instance_data = get_my_data_ptr(get_dispatch_key(my_map_data->gpu), layer_data_map);
-        local_pCreateInfo->surface =
-            (VkSurfaceKHR)instance_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pCreateInfo->surface)];
-    }
-
-    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
-                          ->CreateSwapchainKHR(device, (const VkSwapchainCreateInfoKHR *)local_pCreateInfo, pAllocator, pSwapchain);
-    if (local_pCreateInfo)
-        delete local_pCreateInfo;
-    if (VK_SUCCESS == result) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        uint64_t unique_id =global_unique_id++;
-        my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*pSwapchain);
-        *pSwapchain = reinterpret_cast<VkSwapchainKHR &>(unique_id);
-    }
-    return result;
-}
-
-VkResult explicit_GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
-                                        VkImage *pSwapchainImages) {
-    // UNWRAP USES:
-    //  0 : swapchain,VkSwapchainKHR, pSwapchainImages,VkImage
-    layer_data *my_device_data = get_my_data_ptr(get_dispatch_key(device), layer_data_map);
-    if (VK_NULL_HANDLE != swapchain) {
-        std::lock_guard<std::mutex> lock(global_lock);
-        swapchain = (VkSwapchainKHR)my_device_data->unique_id_mapping[reinterpret_cast<uint64_t &>(swapchain)];
-    }
-    VkResult result = get_dispatch_table(unique_objects_device_table_map, device)
-                          ->GetSwapchainImagesKHR(device, swapchain, pSwapchainImageCount, pSwapchainImages);
-    // TODO : Need to add corresponding code to delete these images
-    if (VK_SUCCESS == result) {
-        if ((*pSwapchainImageCount > 0) && pSwapchainImages) {
-            uint64_t unique_id = 0;
-            std::lock_guard<std::mutex> lock(global_lock);
-            for (uint32_t i = 0; i < *pSwapchainImageCount; ++i) {
-                unique_id = global_unique_id++;
-                my_device_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(pSwapchainImages[i]);
-                pSwapchainImages[i] = reinterpret_cast<VkImage &>(unique_id);
-            }
-        }
-    }
-    return result;
-}
-
- #ifndef __ANDROID__
-VkResult explicit_GetPhysicalDeviceDisplayPropertiesKHR(VkPhysicalDevice physicalDevice, uint32_t* pPropertyCount, VkDisplayPropertiesKHR* pProperties)
-{
-    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    safe_VkDisplayPropertiesKHR* local_pProperties = NULL;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        if (pProperties) {
-            local_pProperties = new safe_VkDisplayPropertiesKHR[*pPropertyCount];
-            for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-                local_pProperties[idx0].initialize(&pProperties[idx0]);
-                if (pProperties[idx0].display) {
-                    local_pProperties[idx0].display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(pProperties[idx0].display)];
-                }
-            }
-        }
-    }
-
-    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetPhysicalDeviceDisplayPropertiesKHR(physicalDevice, pPropertyCount, ( VkDisplayPropertiesKHR*)local_pProperties);
-    if (result == VK_SUCCESS && pProperties)
-    {
-        for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-            std::lock_guard<std::mutex> lock(global_lock);
-
-            uint64_t unique_id = global_unique_id++;
-            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].display);
-            pProperties[idx0].display = reinterpret_cast<VkDisplayKHR&>(unique_id);
-            pProperties[idx0].displayName = local_pProperties[idx0].displayName;
-            pProperties[idx0].physicalDimensions = local_pProperties[idx0].physicalDimensions;
-            pProperties[idx0].physicalResolution = local_pProperties[idx0].physicalResolution;
-            pProperties[idx0].supportedTransforms = local_pProperties[idx0].supportedTransforms;
-            pProperties[idx0].planeReorderPossible = local_pProperties[idx0].planeReorderPossible;
-            pProperties[idx0].persistentContent = local_pProperties[idx0].persistentContent;
-        }
-    }
-    if (local_pProperties)
-        delete[] local_pProperties;
-    return result;
-}
-
-VkResult explicit_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice, uint32_t planeIndex, uint32_t* pDisplayCount, VkDisplayKHR* pDisplays)
-{
-    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayPlaneSupportedDisplaysKHR(physicalDevice, planeIndex, pDisplayCount, pDisplays);
-    if (VK_SUCCESS == result) {
-        if ((*pDisplayCount > 0) && pDisplays) {
-            std::lock_guard<std::mutex> lock(global_lock);
-            for (uint32_t i = 0; i < *pDisplayCount; i++) {
-		    auto it = my_map_data->unique_id_mapping.find(reinterpret_cast<const uint64_t &> (pDisplays[i]));
-                assert (it !=  my_map_data->unique_id_mapping.end());
-                pDisplays[i] = reinterpret_cast<VkDisplayKHR&> (it->second);
-            }
-        }
-    }
-    return result;
-}
-
-
-VkResult explicit_GetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice, VkDisplayKHR display, uint32_t* pPropertyCount, VkDisplayModePropertiesKHR* pProperties)
-{
-    layer_data *my_map_data = get_my_data_ptr(get_dispatch_key(physicalDevice), layer_data_map);
-    safe_VkDisplayModePropertiesKHR* local_pProperties = NULL;
-    {
-        std::lock_guard<std::mutex> lock(global_lock);
-        display = (VkDisplayKHR)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(display)];
-        if (pProperties) {
-            local_pProperties = new safe_VkDisplayModePropertiesKHR[*pPropertyCount];
-            for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-                local_pProperties[idx0].initialize(&pProperties[idx0]);
-            }
-        }
-    }
-
-    VkResult result = get_dispatch_table(unique_objects_instance_table_map, physicalDevice)->GetDisplayModePropertiesKHR(physicalDevice, display, pPropertyCount, ( VkDisplayModePropertiesKHR*)local_pProperties);
-    if (result == VK_SUCCESS && pProperties)
-    {
-        for (uint32_t idx0=0; idx0<*pPropertyCount; ++idx0) {
-            std::lock_guard<std::mutex> lock(global_lock);
-
-            uint64_t unique_id = global_unique_id++;
-            my_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(local_pProperties[idx0].displayMode);
-            pProperties[idx0].displayMode = reinterpret_cast<VkDisplayModeKHR&>(unique_id);
-            pProperties[idx0].parameters.visibleRegion.width = local_pProperties[idx0].parameters.visibleRegion.width;
-            pProperties[idx0].parameters.visibleRegion.height = local_pProperties[idx0].parameters.visibleRegion.height;
-            pProperties[idx0].parameters.refreshRate = local_pProperties[idx0].parameters.refreshRate;
-        }
-    }
-    if (local_pProperties)
-        delete[] local_pProperties;
-    return result;
-}
-#endif
 } // namespace unique_objects
diff --git a/layers/vk_layer_config.cpp b/layers/vk_layer_config.cpp
index ec50744..d8fe87d 100644
--- a/layers/vk_layer_config.cpp
+++ b/layers/vk_layer_config.cpp
@@ -21,14 +21,15 @@
  * Author: Tobin Ehlis <tobin@lunarg.com>
  * Author: Mark Lobodzinski <mark@lunarg.com>
  **************************************************************************/
-#include <fstream>
-#include <string>
-#include <map>
-#include <string.h>
-#include <vulkan/vk_layer.h>
-#include <iostream>
 #include "vk_layer_config.h"
 #include "vulkan/vk_sdk_platform.h"
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <string.h>
+#include <string>
+#include <sys/stat.h>
+#include <vulkan/vk_layer.h>
 
 #define MAX_CHARS_PER_LINE 4096
 
@@ -49,6 +50,25 @@
 
 static ConfigFile g_configFileObj;
 
+std::string getEnvironment(const char *variable) {
+#if !defined(__ANDROID__) && !defined(_WIN32)
+    const char *output = getenv(variable);
+    return output == NULL ? "" : output;
+#elif defined(_WIN32)
+    int size = GetEnvironmentVariable(variable, NULL, 0);
+    if (size == 0) {
+        return "";
+    }
+    char *buffer = new char[size];
+    GetEnvironmentVariable(variable, buffer, size);
+    std::string output = buffer;
+    delete[] buffer;
+    return output;
+#else
+    return "";
+#endif
+}
+
 const char *getLayerOption(const char *_option) { return g_configFileObj.getOption(_option); }
 
 // If option is NULL or stdout, return stdout, otherwise try to open option
@@ -155,7 +175,19 @@
 const char *ConfigFile::getOption(const std::string &_option) {
     std::map<std::string, std::string>::const_iterator it;
     if (!m_fileIsParsed) {
-        parseFile("vk_layer_settings.txt");
+        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
+
+        // If the path exists use it, else use vk_layer_settings
+        struct stat info;
+        if (stat(envPath.c_str(), &info) == 0) {
+            // If this is a directory, look for vk_layer_settings within the directory
+            if (info.st_mode & S_IFDIR) {
+                envPath += "/vk_layer_settings.txt";
+            }
+            parseFile(envPath.c_str());
+        } else {
+            parseFile("vk_layer_settings.txt");
+        }
     }
 
     if ((it = m_valueMap.find(_option)) == m_valueMap.end())
@@ -166,7 +198,19 @@
 
 void ConfigFile::setOption(const std::string &_option, const std::string &_val) {
     if (!m_fileIsParsed) {
-        parseFile("vk_layer_settings.txt");
+        std::string envPath = getEnvironment("VK_LAYER_SETTINGS_PATH");
+
+        // If the path exists use it, else use vk_layer_settings
+        struct stat info;
+        if (stat(envPath.c_str(), &info) == 0) {
+            // If this is a directory, look for vk_layer_settings within the directory
+            if (info.st_mode & S_IFDIR) {
+                envPath += "/vk_layer_settings.txt";
+            }
+            parseFile(envPath.c_str());
+        } else {
+            parseFile("vk_layer_settings.txt");
+        }
     }
 
     m_valueMap[_option] = _val;
diff --git a/layers/vk_layer_logging.h b/layers/vk_layer_logging.h
index 11405e3..3dae24c 100644
--- a/layers/vk_layer_logging.h
+++ b/layers/vk_layer_logging.h
@@ -209,11 +209,9 @@
     if (!strcmp(funcName, "vkDestroyDebugReportCallbackEXT")) {
         return (PFN_vkVoidFunction)vkDestroyDebugReportCallbackEXT;
     }
-
     if (!strcmp(funcName, "vkDebugReportMessageEXT")) {
         return (PFN_vkVoidFunction)vkDebugReportMessageEXT;
     }
-
     return NULL;
 }
 
diff --git a/layers/vk_layer_settings.txt b/layers/vk_layer_settings.txt
index 3674035..f5dcb5f 100644
--- a/layers/vk_layer_settings.txt
+++ b/layers/vk_layer_settings.txt
@@ -1,59 +1,57 @@
-# This is an example vk_layer_settings.txt file.
+################################################################################
 #
-#  This file allows for per-layer settings which can dynamically affect layer
-#  behavior. Comments in this file are denoted with the "#" char.
-#  Settings lines are of the form "<LayerIdentifier>.<SettingName> = <SettingValue>"
+#  This file contains per-layer settings that configure layer behavior at
+#  execution time. Comments in this file are denoted with the "#" char.
+#  Settings lines are of the form:
+#      "<LayerIdentifier>.<SettingName> = <SettingValue>"
 #
-#  <LayerIdentifier> is typically the official layer name, minus the VK_LAYER prefix
-#  and all lower-camel-case -- i.e., for VK_LAYER_LUNARG_core_validation, the layer
-#  identifier is 'lunarg_core_validation', and for VK_LAYER_GOOGLE_threading the layer
-#  identifier is 'google_threading'.
+#  <LayerIdentifier> is typically the official layer name, minus the VK_LAYER
+#  prefix and all lower-camel-case -- i.e., for VK_LAYER_LUNARG_core_validation,
+#  the layer identifier is 'lunarg_core_validation', and for
+#  VK_LAYER_GOOGLE_threading the layeridentifier is 'google_threading'.
 #
-#  There are some common settings that are used by each layer.
-#  Below is a general description of three common settings, followed by
-#  actual template settings for each layer in the SDK.
-#
-# Common settings descriptions:
-# =============================
+################################################################################
+################################################################################
+# Validation Layer Common Settings:
+# =================================
 #
 #   DEBUG_ACTION:
 #   =============
-#   <LayerIdentifier>.debug_action : This is an enum value indicating what action is to
-#    be taken when a layer wants to report information. Possible settings values
-#    are defined in the vk_layer.h header file. These settings are:
-#    VK_DBG_LAYER_ACTION_IGNORE - Take no action
-#    VK_DBG_LAYER_ACTION_LOG_MSG - Log a txt message to stdout or to a log file
-#       specified via the <LayerIdentifier>.log_filename setting (see below)
+#   <LayerIdentifier>.debug_action : This is an enum value indicating what
+#    action is to be taken when a layer wants to report information.
+#    Possible settings values are defined in the vk_layer.h header file.
+#    These settings are:
+#    VK_DBG_LAYER_ACTION_IGNORE - Take no action.
+#    VK_DBG_LAYER_ACTION_LOG_MSG - Log a txt message to stdout or to a log filename
+#       specified via the <LayerIdentifier>.log_filename setting (see below).
 #    VK_DBG_LAYER_ACTION_CALLBACK - Call user defined callback function(s) that
 #       have been registered via the VK_EXT_debug_report extension. Since
 #       app must register callback, this is a NOOP for the settings file.
-#    VK_DBG_LAYER_DEBUG_OUTPUT [Windows only] - Log a txt message using the Windows
-#       OutputDebugString function -- messages will show up in Visual Studio output
-#       window, for instance.
+#    VK_DBG_LAYER_DEBUG_OUTPUT [Windows only] - Log a txt message using the
+#       Windows OutputDebugString function -- messages will show up in the
+#       Visual Studio output window, for instance.
 #    VK_DBG_LAYER_ACTION_BREAK - Trigger a breakpoint.
 #
 #   REPORT_FLAGS:
 #   =============
-#   <LayerIdentifier>.report_flags : This is a comma-delineated list of options telling
-#    the layer what types of messages it should report back. Options are:
-#    info - Report informational messages
-#    warn - Report warnings from using the API in a manner which may lead to undefined
-#           behavior or to warn the user of common trouble spots. A warning does NOT
-#           necessarily signify illegal application behavior.
-#    perf - Report using the API in a way that may cause suboptimal performance
-#    error - Report errors in API usage
-#    debug - For layer development. Report messages for debugging layer behavior
+#   <LayerIdentifier>.report_flags : This is a comma-delineated list of options
+#    telling the layer what types of messages it should report back.
+#    Options are:
+#    info - Report informational messages.
+#    warn - Report warnings from using the API in a manner which may lead to
+#           undefined behavior or to warn the user of common trouble spots.
+#           A warning does NOT necessarily signify illegal application behavior.
+#    perf - Report using the API in a way that may cause suboptimal performance.
+#    error - Report errors in API usage.
+#    debug - For layer development. Report messages for debugging layer
+#            behavior.
 #
 #   LOG_FILENAME:
 #   =============
-#   <LayerIdentifier>.log_filename : output filename. Can be relative to location of
-#      vk_layer_settings.txt file, or an absolute path. If no filename is
-#      specified or if filename has invalid path, then stdout is used by default.
-#
-#
-#
-# Example of actual settings for each layer:
-# ==========================================
+#   <LayerIdentifier>.log_filename : output filename. Can be relative to
+#      location of vk_layer_settings.txt file, or an absolute path. If no
+#      filename is specified or if filename has invalid path, then stdout
+#      is used by default.
 #
 
 # VK_LAYER_LUNARG_core_validation Settings
@@ -90,3 +88,4 @@
 google_unique_objects.debug_action = VK_DBG_LAYER_ACTION_LOG_MSG
 google_unique_objects.report_flags = error,warn,perf
 google_unique_objects.log_filename = stdout
+################################################################################
diff --git a/layers/vk_layer_utils.cpp b/layers/vk_layer_utils.cpp
index 412a5a3..4ad1989 100644
--- a/layers/vk_layer_utils.cpp
+++ b/layers/vk_layer_utils.cpp
@@ -230,12 +230,12 @@
 };
 
 // Return true if format is a depth or stencil format
-bool vk_format_is_depth_or_stencil(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_depth_or_stencil(VkFormat format) {
     return (vk_format_is_depth_and_stencil(format) || vk_format_is_depth_only(format) || vk_format_is_stencil_only(format));
 }
 
 // Return true if format contains depth and stencil information
-bool vk_format_is_depth_and_stencil(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_depth_and_stencil(VkFormat format) {
     bool is_ds = false;
 
     switch (format) {
@@ -251,10 +251,10 @@
 }
 
 // Return true if format is a stencil-only format
-bool vk_format_is_stencil_only(VkFormat format) { return (format == VK_FORMAT_S8_UINT); }
+VK_LAYER_EXPORT bool vk_format_is_stencil_only(VkFormat format) { return (format == VK_FORMAT_S8_UINT); }
 
 // Return true if format is a depth-only format
-bool vk_format_is_depth_only(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_depth_only(VkFormat format) {
     bool is_depth = false;
 
     switch (format) {
@@ -271,7 +271,7 @@
 }
 
 // Return true if format is of time UNORM
-bool vk_format_is_norm(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_norm(VkFormat format) {
     bool is_norm = false;
 
     switch (format) {
@@ -346,10 +346,10 @@
 };
 
 // Return true if format is an integer format
-bool vk_format_is_int(VkFormat format) { return (vk_format_is_sint(format) || vk_format_is_uint(format)); }
+VK_LAYER_EXPORT bool vk_format_is_int(VkFormat format) { return (vk_format_is_sint(format) || vk_format_is_uint(format)); }
 
 // Return true if format is an unsigned integer format
-bool vk_format_is_uint(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_uint(VkFormat format) {
     bool is_uint = false;
 
     switch (format) {
@@ -384,7 +384,7 @@
 }
 
 // Return true if format is a signed integer format
-bool vk_format_is_sint(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_sint(VkFormat format) {
     bool is_sint = false;
 
     switch (format) {
@@ -419,7 +419,7 @@
 }
 
 // Return true if format is a floating-point format
-bool vk_format_is_float(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_float(VkFormat format) {
     bool is_float = false;
 
     switch (format) {
@@ -449,7 +449,7 @@
 }
 
 // Return true if format is in the SRGB colorspace
-bool vk_format_is_srgb(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_srgb(VkFormat format) {
     bool is_srgb = false;
 
     switch (format) {
@@ -491,10 +491,12 @@
 }
 
 // Return true if format is compressed
-bool vk_format_is_compressed(VkFormat format) {
+VK_LAYER_EXPORT bool vk_format_is_compressed(VkFormat format) {
     switch (format) {
     case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
     case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
+    case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
+    case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
     case VK_FORMAT_BC2_UNORM_BLOCK:
     case VK_FORMAT_BC2_SRGB_BLOCK:
     case VK_FORMAT_BC3_UNORM_BLOCK:
@@ -550,8 +552,101 @@
         return false;
     }
 }
+
+// Return compressed block sizes for block compressed formats
+VK_LAYER_EXPORT VkExtent2D vk_format_compressed_block_size(VkFormat format) {
+    VkExtent2D block_size = { 1, 1 };
+    switch (format) {
+    case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
+    case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
+    case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
+    case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
+    case VK_FORMAT_BC2_UNORM_BLOCK:
+    case VK_FORMAT_BC2_SRGB_BLOCK:
+    case VK_FORMAT_BC3_UNORM_BLOCK:
+    case VK_FORMAT_BC3_SRGB_BLOCK:
+    case VK_FORMAT_BC4_UNORM_BLOCK:
+    case VK_FORMAT_BC4_SNORM_BLOCK:
+    case VK_FORMAT_BC5_UNORM_BLOCK:
+    case VK_FORMAT_BC5_SNORM_BLOCK:
+    case VK_FORMAT_BC6H_UFLOAT_BLOCK:
+    case VK_FORMAT_BC6H_SFLOAT_BLOCK:
+    case VK_FORMAT_BC7_UNORM_BLOCK:
+    case VK_FORMAT_BC7_SRGB_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
+    case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+    case VK_FORMAT_EAC_R11_UNORM_BLOCK:
+    case VK_FORMAT_EAC_R11_SNORM_BLOCK:
+    case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
+    case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
+    case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
+        block_size = { 4, 4 };
+        break;
+    case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
+        block_size = { 5, 4 };
+        break;
+    case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
+        block_size = { 5, 5 };
+        break;
+    case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
+        block_size = { 6, 5 };
+        break;
+    case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
+        block_size = { 6, 6 };
+        break;
+    case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
+        block_size = { 8, 5 };
+        break;
+    case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
+        block_size = { 8, 6 };
+        break;
+    case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
+        block_size = { 8, 8 };
+        break;
+    case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
+        block_size = { 10, 5 };
+        break;
+    case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
+        block_size = { 10, 6 };
+        break;
+    case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
+        block_size = { 10, 8 };
+        break;
+    case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
+        block_size = { 10, 10 };
+        break;
+    case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
+        block_size = { 12, 10 };
+        break;
+    case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
+    case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
+        block_size = { 12, 12 };
+        break;
+    default:
+        break;
+    }
+    return block_size;
+}
+
 // Return format class of the specified format
-VkFormatCompatibilityClass vk_format_get_compatibility_class(VkFormat format) {
+VK_LAYER_EXPORT VkFormatCompatibilityClass vk_format_get_compatibility_class(VkFormat format) {
     auto item = vk_format_table.find(format);
     if (item != vk_format_table.end()) {
         return item->second.format_class;
@@ -560,7 +655,7 @@
 }
 
 // Return size, in bytes, of a pixel of the specified format
-size_t vk_format_get_size(VkFormat format) {
+VK_LAYER_EXPORT size_t vk_format_get_size(VkFormat format) {
     auto item = vk_format_table.find(format);
     if (item != vk_format_table.end()) {
         return item->second.size;
@@ -578,7 +673,7 @@
 }
 
 // Perform a zero-tolerant modulo operation
-VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor) {
+VK_LAYER_EXPORT VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor) {
     VkDeviceSize result = 0;
     if (divisor != 0) {
         result = dividend % divisor;
@@ -595,7 +690,7 @@
 static const uint8_t UTF8_DATA_BYTE_CODE = 0x80;
 static const uint8_t UTF8_DATA_BYTE_MASK = 0xC0;
 
-VkStringErrorFlags vk_string_validate(const int max_length, const char *utf8) {
+VK_LAYER_EXPORT VkStringErrorFlags vk_string_validate(const int max_length, const char *utf8) {
     VkStringErrorFlags result = VK_STRING_ERROR_NONE;
     int num_char_bytes = 0;
     int i, j;
@@ -630,7 +725,7 @@
 }
 
 // Utility function for finding a text string in another string
-bool white_list(const char *item, const char *list) {
+VK_LAYER_EXPORT bool white_list(const char *item, const char *list) {
     std::string candidate(item);
     std::string white_list(list);
     return (white_list.find(candidate) != std::string::npos);
@@ -647,8 +742,8 @@
 // If a vk_layer_settings.txt file is present and an application defines a debug callback, both callbacks
 // will be active.  If no vk_layer_settings.txt file is present, creating an application-defined debug
 // callback will cause the default callbacks to be unregisterd and removed.
-void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
-                         const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
+VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
+                                         const VkAllocationCallbacks *pAllocator, const char *layer_identifier) {
 
     VkDebugReportCallbackEXT callback = VK_NULL_HANDLE;
 
diff --git a/layers/vk_layer_utils.h b/layers/vk_layer_utils.h
index 623f0c5..0008907 100644
--- a/layers/vk_layer_utils.h
+++ b/layers/vk_layer_utils.h
@@ -90,8 +90,8 @@
 } VkStringErrorFlagBits;
 typedef VkFlags VkStringErrorFlags;
 
-void layer_debug_actions(debug_report_data* report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
-    const VkAllocationCallbacks *pAllocator, const char* layer_identifier);
+VK_LAYER_EXPORT void layer_debug_actions(debug_report_data *report_data, std::vector<VkDebugReportCallbackEXT> &logging_callback,
+                                         const VkAllocationCallbacks *pAllocator, const char *layer_identifier);
 
 static inline bool vk_format_is_undef(VkFormat format) { return (format == VK_FORMAT_UNDEFINED); }
 
@@ -104,19 +104,20 @@
     return !(vk_format_is_undef(format) || vk_format_is_depth_or_stencil(format));
 }
 
-bool vk_format_is_norm(VkFormat format);
-bool vk_format_is_int(VkFormat format);
-bool vk_format_is_sint(VkFormat format);
-bool vk_format_is_uint(VkFormat format);
-bool vk_format_is_float(VkFormat format);
-bool vk_format_is_srgb(VkFormat format);
-bool vk_format_is_compressed(VkFormat format);
-size_t vk_format_get_size(VkFormat format);
-unsigned int vk_format_get_channel_count(VkFormat format);
-VkFormatCompatibilityClass vk_format_get_compatibility_class(VkFormat format);
-VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor);
-VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
-bool white_list(const char *item, const char *whitelist);
+VK_LAYER_EXPORT bool vk_format_is_norm(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_int(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_sint(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_uint(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_float(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_srgb(VkFormat format);
+VK_LAYER_EXPORT bool vk_format_is_compressed(VkFormat format);
+VK_LAYER_EXPORT VkExtent2D vk_format_compressed_block_size(VkFormat format);
+VK_LAYER_EXPORT size_t vk_format_get_size(VkFormat format);
+VK_LAYER_EXPORT unsigned int vk_format_get_channel_count(VkFormat format);
+VK_LAYER_EXPORT VkFormatCompatibilityClass vk_format_get_compatibility_class(VkFormat format);
+VK_LAYER_EXPORT VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor);
+VK_LAYER_EXPORT VkStringErrorFlags vk_string_validate(const int max_length, const char *char_array);
+VK_LAYER_EXPORT bool white_list(const char *item, const char *whitelist);
 
 static inline int u_ffs(int val) {
 #ifdef WIN32
diff --git a/layers/vk_validation_error_database.txt b/layers/vk_validation_error_database.txt
new file mode 100644
index 0000000..db74eb3
--- /dev/null
+++ b/layers/vk_validation_error_database.txt
@@ -0,0 +1,2294 @@
+# This is a database file with validation error check information
+# Comments are denoted with '#' char
+# The format of the lines is:
+# <error_enum>~^~<check_implemented>~^~<testname>~^~<api>~^~<errormsg>~^~<note>
+# error_enum: Unique error enum for this check of format VALIDATION_ERROR_<uniqueid>
+# check_implemented: 'Y' if check has been implemented in layers, 'U' for unknown, or 'N' for not implemented
+# testname: Name of validation test for this check, 'Unknown' for unknown, or 'None' if not implmented
+# api: Vulkan API function that this check is related to
+# errormsg: The unique error message for this check that includes spec language and link
+# note: Free txt field with any custom notes related to the check in question
+VALIDATION_ERROR_00000~^~U~^~Unknown~^~vkGetInstanceProcAddr~^~For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'If instance is not NULL, instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.8)~^~
+VALIDATION_ERROR_00001~^~U~^~Unknown~^~vkGetInstanceProcAddr~^~For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.8)~^~
+VALIDATION_ERROR_00002~^~U~^~Unknown~^~vkGetDeviceProcAddr~^~For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.15)~^~
+VALIDATION_ERROR_00003~^~U~^~Unknown~^~vkGetDeviceProcAddr~^~For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.15)~^~
+VALIDATION_ERROR_00004~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pCreateInfo must be a pointer to a valid VkInstanceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)~^~
+VALIDATION_ERROR_00005~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)~^~
+VALIDATION_ERROR_00006~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pInstance must be a pointer to a VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)~^~
+VALIDATION_ERROR_00007~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'sType must be VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00008~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00009~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00010~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pApplicationInfo is not NULL, pApplicationInfo must be a pointer to a valid VkApplicationInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00011~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If enabledLayerCount is not 0, ppEnabledLayerNames must be a pointer to an array of enabledLayerCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00012~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If enabledExtensionCount is not 0, ppEnabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)~^~
+VALIDATION_ERROR_00013~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'apiVersion must be zero, or otherwise it must be a version that the implementation supports, or supports an effective substitute for' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)~^~
+VALIDATION_ERROR_00014~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'sType must be VK_STRUCTURE_TYPE_APPLICATION_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)~^~
+VALIDATION_ERROR_00015~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)~^~
+VALIDATION_ERROR_00016~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pApplicationName is not NULL, pApplicationName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)~^~
+VALIDATION_ERROR_00017~^~U~^~Unknown~^~vkCreateInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pEngineName is not NULL, pEngineName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)~^~
+VALIDATION_ERROR_00018~^~U~^~Unknown~^~vkDestroyInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'All child objects created using instance must have been destroyed prior to destroying instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)~^~
+VALIDATION_ERROR_00019~^~U~^~Unknown~^~vkDestroyInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)~^~
+VALIDATION_ERROR_00020~^~U~^~Unknown~^~vkDestroyInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)~^~
+VALIDATION_ERROR_00021~^~Y~^~Unknown~^~vkDestroyInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If instance is not NULL, instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)~^~
+VALIDATION_ERROR_00022~^~U~^~Unknown~^~vkDestroyInstance~^~For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)~^~
+VALIDATION_ERROR_00023~^~Y~^~Unknown~^~vkEnumeratePhysicalDevices~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)~^~
+VALIDATION_ERROR_00024~^~U~^~Unknown~^~vkEnumeratePhysicalDevices~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pPhysicalDeviceCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)~^~
+VALIDATION_ERROR_00025~^~U~^~Unknown~^~vkEnumeratePhysicalDevices~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'If the value referenced by pPhysicalDeviceCount is not 0, and pPhysicalDevices is not NULL, pPhysicalDevices must be a pointer to an array of pPhysicalDeviceCount VkPhysicalDevice handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)~^~
+VALIDATION_ERROR_00026~^~Y~^~Unknown~^~vkGetPhysicalDeviceProperties~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceProperties)~^~
+VALIDATION_ERROR_00027~^~U~^~Unknown~^~vkGetPhysicalDeviceProperties~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pProperties must be a pointer to a VkPhysicalDeviceProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceProperties)~^~
+VALIDATION_ERROR_00028~^~U~^~Unknown~^~vkGetPhysicalDeviceQueueFamilyProperties~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)~^~
+VALIDATION_ERROR_00029~^~U~^~Unknown~^~vkGetPhysicalDeviceQueueFamilyProperties~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pQueueFamilyPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)~^~
+VALIDATION_ERROR_00030~^~U~^~Unknown~^~vkGetPhysicalDeviceQueueFamilyProperties~^~For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'If the value referenced by pQueueFamilyPropertyCount is not 0, and pQueueFamilyProperties is not NULL, pQueueFamilyProperties must be a pointer to an array of pQueueFamilyPropertyCount VkQueueFamilyProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)~^~
+VALIDATION_ERROR_00031~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)~^~
+VALIDATION_ERROR_00032~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pCreateInfo must be a pointer to a valid VkDeviceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)~^~
+VALIDATION_ERROR_00033~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)~^~
+VALIDATION_ERROR_00034~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pDevice must be a pointer to a VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)~^~
+VALIDATION_ERROR_00035~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'The queueFamilyIndex member of any given element of pQueueCreateInfos must be unique within pQueueCreateInfos' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00036~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'sType must be VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00037~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00038~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00039~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pQueueCreateInfos must be a pointer to an array of queueCreateInfoCount valid VkDeviceQueueCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00040~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If enabledLayerCount is not 0, ppEnabledLayerNames must be a pointer to an array of enabledLayerCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00041~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If enabledExtensionCount is not 0, ppEnabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00042~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If pEnabledFeatures is not NULL, pEnabledFeatures must be a pointer to a valid VkPhysicalDeviceFeatures structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00043~^~U~^~Unknown~^~vkCreateDevice~^~For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'queueCreateInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)~^~
+VALIDATION_ERROR_00049~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'All child objects created on device must have been destroyed prior to destroying device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)~^~
+VALIDATION_ERROR_00050~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If VkAllocationCallbacks were provided when device was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)~^~
+VALIDATION_ERROR_00051~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If no VkAllocationCallbacks were provided when device was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)~^~
+VALIDATION_ERROR_00052~^~Y~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If device is not NULL, device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)~^~
+VALIDATION_ERROR_00053~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)~^~
+VALIDATION_ERROR_00054~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00055~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'sType must be VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00056~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00057~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00058~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueuePriorities must be a pointer to an array of queueCount float values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00059~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_00060~^~U~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be one of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)~^~
+VALIDATION_ERROR_00061~^~U~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueIndex must be less than the number of queues created for the specified queue family index when device was created, via the queueCount member of the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)~^~
+VALIDATION_ERROR_00062~^~Y~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)~^~
+VALIDATION_ERROR_00063~^~U~^~Unknown~^~vkGetDeviceQueue~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueue must be a pointer to a VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)~^~
+VALIDATION_ERROR_00064~^~Y~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)~^~
+VALIDATION_ERROR_00065~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pCreateInfo must be a pointer to a valid VkCommandPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)~^~
+VALIDATION_ERROR_00066~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)~^~
+VALIDATION_ERROR_00067~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pCommandPool must be a pointer to a VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)~^~
+VALIDATION_ERROR_00068~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'queueFamilyIndex must be the index of a queue family available in the calling commands device parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00069~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00070~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00071~^~U~^~Unknown~^~vkCreateCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'flags must be a valid combination of VkCommandPoolCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00072~^~Y~^~None~^~vkResetCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'All VkCommandBuffer objects allocated from commandPool must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)~^~
+VALIDATION_ERROR_00073~^~Y~^~Unknown~^~vkResetCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)~^~
+VALIDATION_ERROR_00074~^~Y~^~Unknown~^~vkResetCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)~^~
+VALIDATION_ERROR_00075~^~U~^~Unknown~^~vkResetCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'flags must be a valid combination of VkCommandPoolResetFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)~^~
+VALIDATION_ERROR_00076~^~U~^~Unknown~^~vkResetCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'commandPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)~^~
+VALIDATION_ERROR_00077~^~Y~^~None~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'All VkCommandBuffer objects allocated from commandPool must not be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00078~^~U~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If VkAllocationCallbacks were provided when commandPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00079~^~U~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If no VkAllocationCallbacks were provided when commandPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00080~^~Y~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00081~^~Y~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If commandPool is not VK_NULL_HANDLE, commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00082~^~U~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00083~^~U~^~Unknown~^~vkDestroyCommandPool~^~For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If commandPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)~^~
+VALIDATION_ERROR_00084~^~Y~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)~^~
+VALIDATION_ERROR_00085~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pAllocateInfo must be a pointer to a valid VkCommandBufferAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)~^~
+VALIDATION_ERROR_00086~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pCommandBuffers must be a pointer to an array of pAllocateInfo::commandBufferCount VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)~^~
+VALIDATION_ERROR_00087~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)~^~
+VALIDATION_ERROR_00088~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)~^~
+VALIDATION_ERROR_00089~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)~^~
+VALIDATION_ERROR_00090~^~Y~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)~^~
+VALIDATION_ERROR_00091~^~U~^~Unknown~^~vkAllocateCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'level must be a valid VkCommandBufferLevel value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)~^~
+VALIDATION_ERROR_00092~^~Y~^~CommandBufferResetErrors~^~vkResetCommandBuffer~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)~^~
+VALIDATION_ERROR_00093~^~U~^~Unknown~^~vkResetCommandBuffer~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must have been allocated from a pool that was created with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)~^~
+VALIDATION_ERROR_00094~^~U~^~Unknown~^~vkResetCommandBuffer~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)~^~
+VALIDATION_ERROR_00095~^~U~^~Unknown~^~vkResetCommandBuffer~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'flags must be a valid combination of VkCommandBufferResetFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)~^~
+VALIDATION_ERROR_00096~^~Y~^~None~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'All elements of pCommandBuffers must not be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00097~^~U~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pCommandBuffers must be a pointer to an array of commandBufferCount VkCommandBuffer handles, each element of which must either be a valid handle or NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00098~^~Y~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00099~^~Y~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00100~^~U~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00101~^~U~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00102~^~U~^~Unknown~^~vkFreeCommandBuffers~^~For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'Each element of pCommandBuffers that is a valid handle must have been created, allocated, or retrieved from commandPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)~^~
+VALIDATION_ERROR_00103~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must not be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00104~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00105~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer was allocated from a VkCommandPool which did not have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, commandBuffer must be in the initial state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00106~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a secondary command buffer, the pInheritanceInfo member of pBeginInfo must be a valid VkCommandBufferInheritanceInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00107~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a secondary command buffer and either the occlusionQueryEnable member of the pInheritanceInfo member of pBeginInfo is VK_FALSE, or the precise occlusion queries feature is not enabled, the queryFlags member of the pInheritanceInfo member pBeginInfo must not contain VK_QUERY_CONTROL_PRECISE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00108~^~Y~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00109~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pBeginInfo must be a pointer to a valid VkCommandBufferBeginInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)~^~
+VALIDATION_ERROR_00110~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the renderPass member of pInheritanceInfo must be a valid VkRenderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00111~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the subpass member of pInheritanceInfo must be a valid subpass index within the renderPass member of pInheritanceInfo' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00112~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the framebuffer member of pInheritanceInfo must be either VK_NULL_HANDLE, or a valid VkFramebuffer that is compatible with the renderPass member of pInheritanceInfo' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00113~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00114~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00115~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'flags must be a valid combination of VkCommandBufferUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)~^~
+VALIDATION_ERROR_00116~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the inherited queries feature is not enabled, occlusionQueryEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00117~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the inherited queries feature is enabled, queryFlags must be a valid combination of VkQueryControlFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00118~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the pipeline statistics queries feature is not enabled, pipelineStatistics must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00119~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00120~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00121~^~U~^~Unknown~^~vkBeginCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'Both of framebuffer, and renderPass that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)~^~
+VALIDATION_ERROR_00122~^~U~^~Unknown~^~vkEndCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)~^~
+VALIDATION_ERROR_00123~^~U~^~Unknown~^~vkEndCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a primary command buffer, there must not be an active render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)~^~
+VALIDATION_ERROR_00124~^~U~^~Unknown~^~vkEndCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'All queries made active during the recording of commandBuffer must have been made inactive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)~^~
+VALIDATION_ERROR_00125~^~Y~^~Unknown~^~vkEndCommandBuffer~^~For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)~^~
+VALIDATION_ERROR_00126~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00127~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00128~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00129~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If submitCount is not 0, pSubmits must be a pointer to an array of submitCount valid VkSubmitInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00130~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00131~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)~^~
+VALIDATION_ERROR_00132~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pSignalSemaphores must currently be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00133~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must either have been recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00134~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must be in the executable state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00135~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers contains commands that execute secondary command buffers, those secondary command buffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00136~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers was recorded with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, it must not have been previously submitted without re-recording that command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00137~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers contains commands that execute secondary command buffers recorded with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, each such secondary command buffer must not have been previously submitted without re-recording that command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00138~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must not contain commands that execute a secondary command buffer, if that secondary command buffer has been recorded in another primary command buffer after it was recorded into this VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00139~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must have been allocated from a VkCommandPool that was created for the same queue family that the calling commands queue belongs to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00140~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must not have been allocated with VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00141~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of VkSemaphore in pWaitSemaphores must refer to a prior signal of that VkSemaphore that will not be consumed by any other wait on that semaphore' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00142~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If the geometry shaders feature is not enabled, any given element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00143~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If the tessellation shaders feature is not enabled, any given element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00144~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'sType must be VK_STRUCTURE_TYPE_SUBMIT_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00145~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00146~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If waitSemaphoreCount is not 0, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00147~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If waitSemaphoreCount is not 0, pWaitDstStageMask must be a pointer to an array of waitSemaphoreCount valid combinations of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00148~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Each element of pWaitDstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00149~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If commandBufferCount is not 0, pCommandBuffers must be a pointer to an array of commandBufferCount valid VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00150~^~Y~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If signalSemaphoreCount is not 0, pSignalSemaphores must be a pointer to an array of signalSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00151~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Each of the elements of pCommandBuffers, the elements of pSignalSemaphores, and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)~^~
+VALIDATION_ERROR_00152~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_PRIMARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00153~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00154~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not be already pending execution in commandBuffer, or appear twice in pCommandBuffers, unless it was recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00155~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not be already pending execution in any other VkCommandBuffer, unless it was recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00156~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must be in the executable state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00157~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated from a VkCommandPool that was created for the same queue family as the VkCommandPool from which commandBuffer was allocated' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00158~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must have been begun with the contents parameter of vkCmdBeginRenderPass set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00159~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00160~^~Y~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'pCommandBuffers must be a pointer to an array of commandBufferCount valid VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00161~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00162~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00163~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00164~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00165~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Both of commandBuffer, and the elements of pCommandBuffers must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_00166~^~Y~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)~^~
+VALIDATION_ERROR_00167~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pCreateInfo must be a pointer to a valid VkFenceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)~^~
+VALIDATION_ERROR_00168~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)~^~
+VALIDATION_ERROR_00169~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFence must be a pointer to a VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)~^~
+VALIDATION_ERROR_00170~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'sType must be VK_STRUCTURE_TYPE_FENCE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)~^~
+VALIDATION_ERROR_00171~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)~^~
+VALIDATION_ERROR_00172~^~U~^~Unknown~^~vkCreateFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'flags must be a valid combination of VkFenceCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)~^~
+VALIDATION_ERROR_00173~^~U~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must not be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00174~^~U~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If VkAllocationCallbacks were provided when fence was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00175~^~U~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If no VkAllocationCallbacks were provided when fence was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00176~^~Y~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00177~^~Y~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00178~^~U~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00179~^~U~^~Unknown~^~vkDestroyFence~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If fence is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)~^~
+VALIDATION_ERROR_00180~^~Y~^~Unknown~^~vkGetFenceStatus~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)~^~
+VALIDATION_ERROR_00181~^~Y~^~Unknown~^~vkGetFenceStatus~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)~^~
+VALIDATION_ERROR_00182~^~U~^~Unknown~^~vkGetFenceStatus~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)~^~
+VALIDATION_ERROR_00183~^~U~^~Unknown~^~vkResetFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Any given element of pFences must not currently be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)~^~
+VALIDATION_ERROR_00184~^~Y~^~Unknown~^~vkResetFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)~^~
+VALIDATION_ERROR_00185~^~U~^~Unknown~^~vkResetFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFences must be a pointer to an array of fenceCount valid VkFence handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)~^~
+VALIDATION_ERROR_00186~^~U~^~Unknown~^~vkResetFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fenceCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)~^~
+VALIDATION_ERROR_00187~^~Y~^~Unknown~^~vkResetFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Each element of pFences must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)~^~
+VALIDATION_ERROR_00188~^~Y~^~Unknown~^~vkWaitForFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)~^~
+VALIDATION_ERROR_00189~^~U~^~Unknown~^~vkWaitForFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFences must be a pointer to an array of fenceCount valid VkFence handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)~^~
+VALIDATION_ERROR_00190~^~U~^~Unknown~^~vkWaitForFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fenceCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)~^~
+VALIDATION_ERROR_00191~^~Y~^~Unknown~^~vkWaitForFences~^~For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Each element of pFences must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)~^~
+VALIDATION_ERROR_00192~^~Y~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)~^~
+VALIDATION_ERROR_00193~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pCreateInfo must be a pointer to a valid VkSemaphoreCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)~^~
+VALIDATION_ERROR_00194~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)~^~
+VALIDATION_ERROR_00195~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pSemaphore must be a pointer to a VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)~^~
+VALIDATION_ERROR_00196~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'sType must be VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)~^~
+VALIDATION_ERROR_00197~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)~^~
+VALIDATION_ERROR_00198~^~U~^~Unknown~^~vkCreateSemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)~^~
+VALIDATION_ERROR_00199~^~Y~^~InUseDestroyedSignaled~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'semaphore must not be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00200~^~U~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If VkAllocationCallbacks were provided when semaphore was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00201~^~U~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If no VkAllocationCallbacks were provided when semaphore was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00202~^~Y~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00203~^~Y~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00204~^~U~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00205~^~U~^~Unknown~^~vkDestroySemaphore~^~For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If semaphore is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)~^~
+VALIDATION_ERROR_00206~^~Y~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)~^~
+VALIDATION_ERROR_00207~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'pCreateInfo must be a pointer to a valid VkEventCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)~^~
+VALIDATION_ERROR_00208~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)~^~
+VALIDATION_ERROR_00209~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'pEvent must be a pointer to a VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)~^~
+VALIDATION_ERROR_00210~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'sType must be VK_STRUCTURE_TYPE_EVENT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)~^~
+VALIDATION_ERROR_00211~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)~^~
+VALIDATION_ERROR_00212~^~U~^~Unknown~^~vkCreateEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)~^~
+VALIDATION_ERROR_00213~^~Y~^~InUseDestroyedSignaled~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'All submitted commands that refer to event must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00214~^~U~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If VkAllocationCallbacks were provided when event was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00215~^~U~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If no VkAllocationCallbacks were provided when event was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00216~^~Y~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00217~^~Y~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00218~^~U~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00219~^~U~^~Unknown~^~vkDestroyEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If event is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)~^~
+VALIDATION_ERROR_00220~^~Y~^~Unknown~^~vkGetEventStatus~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)~^~
+VALIDATION_ERROR_00221~^~Y~^~Unknown~^~vkGetEventStatus~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)~^~
+VALIDATION_ERROR_00222~^~U~^~Unknown~^~vkGetEventStatus~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)~^~
+VALIDATION_ERROR_00223~^~Y~^~Unknown~^~vkSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)~^~
+VALIDATION_ERROR_00224~^~Y~^~Unknown~^~vkSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)~^~
+VALIDATION_ERROR_00225~^~U~^~Unknown~^~vkSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)~^~
+VALIDATION_ERROR_00226~^~U~^~Unknown~^~vkResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must not be waited on by a vkCmdWaitEvents command that is currently executing' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)~^~
+VALIDATION_ERROR_00227~^~Y~^~Unknown~^~vkResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)~^~
+VALIDATION_ERROR_00228~^~Y~^~Unknown~^~vkResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)~^~
+VALIDATION_ERROR_00229~^~U~^~Unknown~^~vkResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)~^~
+VALIDATION_ERROR_00230~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00231~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00232~^~Y~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00233~^~Y~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00234~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00235~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00236~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00237~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00238~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00239~^~U~^~Unknown~^~vkCmdSetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and event must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)~^~
+VALIDATION_ERROR_00240~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00241~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00242~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'When this command executes, event must not be waited on by a vkCmdWaitEvents command that is currently executing' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00243~^~Y~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00244~^~Y~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00245~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00246~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00247~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00248~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00249~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00250~^~U~^~Unknown~^~vkCmdResetEvent~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and event must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)~^~
+VALIDATION_ERROR_00251~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must be the bitwise OR of the stageMask parameter used in previous calls to vkCmdSetEvent with any of the members of pEvents and VK_PIPELINE_STAGE_HOST_BIT if any of the members of pEvents was set using vkSetEvent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00252~^~Y~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00253~^~Y~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'pEvents must be a pointer to an array of eventCount valid VkEvent handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00254~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00255~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00256~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00257~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00258~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If memoryBarrierCount is not 0, pMemoryBarriers must be a pointer to an array of memoryBarrierCount valid VkMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00259~^~Y~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If bufferMemoryBarrierCount is not 0, pBufferMemoryBarriers must be a pointer to an array of bufferMemoryBarrierCount valid VkBufferMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00260~^~Y~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If imageMemoryBarrierCount is not 0, pImageMemoryBarriers must be a pointer to an array of imageMemoryBarrierCount valid VkImageMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00261~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00262~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00263~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'eventCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00264~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and the elements of pEvents must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_00265~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00266~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00267~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00268~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00269~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the render pass must have been created with a VkSubpassDependency instance in pDependencies that expresses a dependency from the current subpass to itself. Additionally:srcStageMask must contain a subset of the bit values in the srcStageMask member of that instance of VkSubpassDependencydstStageMask must contain a subset of the bit values in the dstStageMask member of that instance of VkSubpassDependencyThe srcAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the srcAccessMask member of that instance of VkSubpassDependencyThe dstAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the dstAccessMask member of that instance of VkSubpassDependencydependencyFlags must be equal to the dependencyFlags member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00270~^~Y~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00271~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00272~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00273~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00274~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00275~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dependencyFlags must be a valid combination of VkDependencyFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00276~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If memoryBarrierCount is not 0, pMemoryBarriers must be a pointer to an array of memoryBarrierCount valid VkMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00277~^~Y~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If bufferMemoryBarrierCount is not 0, pBufferMemoryBarriers must be a pointer to an array of bufferMemoryBarrierCount valid VkBufferMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00278~^~Y~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If imageMemoryBarrierCount is not 0, pImageMemoryBarriers must be a pointer to an array of imageMemoryBarrierCount valid VkImageMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00279~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00280~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_00281~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)~^~
+VALIDATION_ERROR_00282~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)~^~
+VALIDATION_ERROR_00283~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)~^~
+VALIDATION_ERROR_00284~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)~^~
+VALIDATION_ERROR_00285~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00286~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00287~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to than the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00288~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, srcQueueFamilyIndex and dstQueueFamilyIndex must both be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00289~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, srcQueueFamilyIndex and dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see Section 4.3.1, Queue Family Properties)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00290~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are valid queue families, at least one of them must be the same as the family of the queue that will execute this barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00291~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00292~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00293~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00294~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00295~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)~^~
+VALIDATION_ERROR_00296~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'oldLayout must be VK_IMAGE_LAYOUT_UNDEFINED or the current layout of the image subresources affected by the barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00297~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'newLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00298~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, srcQueueFamilyIndex and dstQueueFamilyIndex must both be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00299~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, srcQueueFamilyIndex and dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see Section 4.3.1, Queue Family Properties)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00300~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are valid queue families, at least one of them must be the same as the family of the queue that will execute this barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00301~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'subresourceRange must be a valid image subresource range for the image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00302~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image has a depth/stencil format with both depth and stencil components, then aspectMask member of subresourceRange must include both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00303~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00304~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00305~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00306~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then image must have been created with VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00307~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00308~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00309~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00310~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00311~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00312~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00313~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'oldLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00314~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'newLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00315~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00316~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'subresourceRange must be a valid VkImageSubresourceRange structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)~^~
+VALIDATION_ERROR_00317~^~Y~^~Unknown~^~vkQueueWaitIdle~^~For more information refer to Vulkan Spec Section '6.5.7. Wait Idle Operations' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueWaitIdle)~^~
+VALIDATION_ERROR_00318~^~Y~^~Unknown~^~vkDeviceWaitIdle~^~For more information refer to Vulkan Spec Section '6.5.7. Wait Idle Operations' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDeviceWaitIdle)~^~
+VALIDATION_ERROR_00319~^~Y~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)~^~
+VALIDATION_ERROR_00320~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pCreateInfo must be a pointer to a valid VkRenderPassCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)~^~
+VALIDATION_ERROR_00321~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)~^~
+VALIDATION_ERROR_00322~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pRenderPass must be a pointer to a VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)~^~
+VALIDATION_ERROR_00323~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any two subpasses operate on attachments with overlapping ranges of the same VkDeviceMemory object, and at least one subpass writes to that area of VkDeviceMemory, a subpass dependency must be included (either directly or via some intermediate subpasses) between them' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00324~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, or the attachment indexed by any element of pPreserveAttachments in any given element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with any other attachment in any subpass (including the same subpass), the VkAttachmentDescription structures describing them must include VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00325~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, or any element of pPreserveAttachments in any given element of pSubpasses is not VK_ATTACHMENT_UNUSED, it must be less than attachmentCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00326~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'The value of any element of the pPreserveAttachments member in any given element of pSubpasses must not be VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00327~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'sType must be VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00328~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00329~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00330~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkAttachmentDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00331~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pSubpasses must be a pointer to an array of subpassCount valid VkSubpassDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00332~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If dependencyCount is not 0, pDependencies must be a pointer to an array of dependencyCount valid VkSubpassDependency structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00333~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'subpassCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)~^~
+VALIDATION_ERROR_00334~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00335~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be a valid combination of VkAttachmentDescriptionFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00336~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00337~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00338~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'loadOp must be a valid VkAttachmentLoadOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00339~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'storeOp must be a valid VkAttachmentStoreOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00340~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'stencilLoadOp must be a valid VkAttachmentLoadOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00341~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'stencilStoreOp must be a valid VkAttachmentStoreOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00342~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'initialLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00343~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'finalLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)~^~
+VALIDATION_ERROR_00347~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pipelineBindPoint must be VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00348~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'colorAttachmentCount must be less than or equal to VkPhysicalDeviceLimits::maxColorAttachments' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00349~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the first use of an attachment in this render pass is as an input attachment, and the attachment is not also used as a color or depth/stencil attachment in the same subpass, then loadOp must not be VK_ATTACHMENT_LOAD_OP_CLEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00350~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pResolveAttachments is not NULL, for each resolve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment must not have the value VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00351~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pResolveAttachments is not NULL, the sample count of each element of pColorAttachments must be anything other than VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00352~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pResolveAttachments must have a sample count of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00353~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pResolveAttachments must have the same VkFormat as its corresponding color attachment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00354~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'All attachments in pColorAttachments and pDepthStencilAttachment that are not VK_ATTACHMENT_UNUSED must have the same sample count' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00355~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any input attachments are VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must not access those input attachments from the fragment shader' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00356~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'The attachment member of any element of pPreserveAttachments must not be VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00357~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pPreserveAttachments must not also be an element of any other member of the subpass description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00358~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any attachment is used as both an input attachment and a color or depth/stencil attachment, then each use must use the same layout' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00359~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00360~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00361~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If inputAttachmentCount is not 0, pInputAttachments must be a pointer to an array of inputAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00362~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If colorAttachmentCount is not 0, pColorAttachments must be a pointer to an array of colorAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00363~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If colorAttachmentCount is not 0, and pResolveAttachments is not NULL, pResolveAttachments must be a pointer to an array of colorAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00364~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pDepthStencilAttachment is not NULL, pDepthStencilAttachment must be a pointer to a valid VkAttachmentReference structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00365~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If preserveAttachmentCount is not 0, pPreserveAttachments must be a pointer to an array of preserveAttachmentCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)~^~
+VALIDATION_ERROR_00366~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'layout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAttachmentReference)~^~
+VALIDATION_ERROR_00367~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'layout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAttachmentReference)~^~
+VALIDATION_ERROR_00368~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00369~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00370~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00371~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00372~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcSubpass must be less than or equal to dstSubpass, unless one of them is VK_SUBPASS_EXTERNAL, to avoid cyclic dependencies and ensure a valid execution order' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00373~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcSubpass and dstSubpass must not both be equal to VK_SUBPASS_EXTERNAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00374~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If srcSubpass is equal to dstSubpass, srcStageMask and dstStageMask must only contain one of VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, or VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00375~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If srcSubpass is equal to dstSubpass, the highest bit value included in srcStageMask must be less than or equal to the lowest bit value in dstStageMask' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00376~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00377~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00378~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00379~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00380~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00381~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00382~^~U~^~Unknown~^~vkCreateRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dependencyFlags must be a valid combination of VkDependencyFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)~^~
+VALIDATION_ERROR_00393~^~Y~^~None~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'All submitted commands that refer to renderPass must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00394~^~U~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If VkAllocationCallbacks were provided when renderPass was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00395~^~U~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If no VkAllocationCallbacks were provided when renderPass was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00396~^~Y~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00397~^~Y~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00398~^~U~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00399~^~U~^~Unknown~^~vkDestroyRenderPass~^~For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If renderPass is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)~^~
+VALIDATION_ERROR_00400~^~Y~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)~^~
+VALIDATION_ERROR_00401~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pCreateInfo must be a pointer to a valid VkFramebufferCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)~^~
+VALIDATION_ERROR_00402~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)~^~
+VALIDATION_ERROR_00403~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pFramebuffer must be a pointer to a VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)~^~
+VALIDATION_ERROR_00404~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'attachmentCount must be equal to the attachment count specified in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00405~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as a color attachment or resolve attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00406~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as a depth/stencil attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00407~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as an input attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00408~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with an VkFormat value that matches the VkFormat specified by the corresponding VkAttachmentDescription in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00409~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with a samples value that matches the samples value specified by the corresponding VkAttachmentDescription in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00410~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have dimensions at least as large as the corresponding framebuffer dimension' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00411~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must only specify a single mip level' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00412~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with the identity swizzle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00413~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'width must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferWidth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00414~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'height must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferHeight' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00415~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'layers must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferLayers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00416~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'sType must be VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00417~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00418~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00419~^~Y~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00420~^~Y~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkImageView handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00421~^~U~^~Unknown~^~vkCreateFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Both of renderPass, and the elements of pAttachments that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)~^~
+VALIDATION_ERROR_00422~^~Y~^~FramebufferInUseDestroyedSignaled~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'All submitted commands that refer to framebuffer must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00423~^~U~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If VkAllocationCallbacks were provided when framebuffer was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00424~^~U~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If no VkAllocationCallbacks were provided when framebuffer was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00425~^~Y~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00426~^~Y~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00427~^~U~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00428~^~U~^~Unknown~^~vkDestroyFramebuffer~^~For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If framebuffer is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)~^~
+VALIDATION_ERROR_00429~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00430~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00431~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00432~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00433~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00434~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout members of the VkAttachmentDescription structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is not VK_IMAGE_LAYOUT_UNDEFINED, then each such initialLayout must be equal to the current layout of the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00435~^~Y~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00436~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pRenderPassBegin must be a pointer to a valid VkRenderPassBeginInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00437~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'contents must be a valid VkSubpassContents value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00438~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00439~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00440~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00441~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)~^~
+VALIDATION_ERROR_00442~^~Y~^~RenderPassClearOpMismatch~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'clearValueCount must be greater than the largest attachment index in renderPass that specifies a loadOp (or stencilLoadOp, if the attachment has a depth/stencil format) of VK_ATTACHMENT_LOAD_OP_CLEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00443~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'sType must be VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00444~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00445~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00446~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'framebuffer must be a valid VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00447~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If clearValueCount is not 0, pClearValues must be a pointer to an array of clearValueCount valid VkClearValue unions' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00448~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'Both of framebuffer, and renderPass must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_00449~^~Y~^~Unknown~^~vkGetRenderAreaGranularity~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)~^~
+VALIDATION_ERROR_00450~^~Y~^~Unknown~^~vkGetRenderAreaGranularity~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)~^~
+VALIDATION_ERROR_00451~^~U~^~Unknown~^~vkGetRenderAreaGranularity~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pGranularity must be a pointer to a VkExtent2D structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)~^~
+VALIDATION_ERROR_00452~^~U~^~Unknown~^~vkGetRenderAreaGranularity~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)~^~
+VALIDATION_ERROR_00453~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The current subpass index must be less than the number of subpasses in the render pass minus one' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00454~^~Y~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00455~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'contents must be a valid VkSubpassContents value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00456~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00457~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00458~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00459~^~U~^~Unknown~^~vkCmdNextSubpass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)~^~
+VALIDATION_ERROR_00460~^~U~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The current subpass index must be equal to the number of subpasses in the render pass minus one' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00461~^~Y~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00462~^~U~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00463~^~U~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00464~^~U~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00465~^~U~^~Unknown~^~vkCmdEndRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)~^~
+VALIDATION_ERROR_00466~^~Y~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)~^~
+VALIDATION_ERROR_00467~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCreateInfo must be a pointer to a valid VkShaderModuleCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)~^~
+VALIDATION_ERROR_00468~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)~^~
+VALIDATION_ERROR_00469~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pShaderModule must be a pointer to a VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)~^~
+VALIDATION_ERROR_00470~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'codeSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00471~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'codeSize must be a multiple of 4. If the VK_NV_glsl_shader extension is enabled and pCode references GLSL code codeSize can be a multiple of 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00472~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must point to valid SPIR-V code, formatted and packed as described by the Khronos SPIR-V Specification. If the VK_NV_glsl_shader extension is enabled pCode can instead reference valid GLSL code and must be written to the GL_KHR_vulkan_glsl extension specification' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00473~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must adhere to the validation rules described by the Validation Rules within a Module section of the SPIR-V Environment appendix. If the VK_NV_glsl_shader extension is enabled pCode can be valid GLSL code with respect to the GL_KHR_vulkan_glsl GLSL extension specification' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00474~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must declare the Shader capability for SPIR-V code' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00475~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'sType must be VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00476~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00477~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00478~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must be a pointer to an array of $codeSize /over 4$ uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_00479~^~U~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If VkAllocationCallbacks were provided when shaderModule was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00480~^~U~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If no VkAllocationCallbacks were provided when shaderModule was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00481~^~Y~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00482~^~Y~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If shaderModule is not VK_NULL_HANDLE, shaderModule must be a valid VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00483~^~U~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00484~^~U~^~Unknown~^~vkDestroyShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If shaderModule is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)~^~
+VALIDATION_ERROR_00485~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the flags member of any given element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1, basePipelineIndex must be less than the index into pCreateInfos that corresponds to that element' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00486~^~Y~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00487~^~Y~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00488~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pCreateInfos must be a pointer to an array of createInfoCount valid VkComputePipelineCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00489~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00490~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pPipelines must be a pointer to an array of createInfoCount VkPipeline handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00491~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'createInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00492~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)~^~
+VALIDATION_ERROR_00493~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, basePipelineHandle must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00494~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, it must be a valid index into the calling commands pCreateInfos parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00495~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineIndex must be -1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00496~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineHandle must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00497~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, it must be a valid handle to a compute VkPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00498~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'The stage member of stage must be VK_SHADER_STAGE_COMPUTE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00499~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'The shader code for the entry point identified by stage and the rest of the state identified by this structure must adhere to the pipeline linking rules described in the Shader Interfaces chapter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00500~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'layout must be consistent with the layout of the compute shader specified in stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00501~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00502~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00503~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'flags must be a valid combination of VkPipelineCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00504~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must be a valid VkPipelineShaderStageCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00505~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00506~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'Both of basePipelineHandle, and layout that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)~^~
+VALIDATION_ERROR_00507~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the geometry shaders feature is not enabled, stage must not be VK_SHADER_STAGE_GEOMETRY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00508~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the tessellation shaders feature is not enabled, stage must not be VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00509~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must not be VK_SHADER_STAGE_ALL_GRAPHICS, or VK_SHADER_STAGE_ALL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00510~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pName must be the name of an OpEntryPoint in module with an execution model that matches stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00511~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00512~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00513~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00514~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must be a valid VkShaderStageFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00515~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'module must be a valid VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00516~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00517~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pSpecializationInfo is not NULL, pSpecializationInfo must be a pointer to a valid VkSpecializationInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_00518~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the flags member of any given element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1, basePipelineIndex must be less than the index into pCreateInfos that corresponds to that element' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00519~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00520~^~Y~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00521~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pCreateInfos must be a pointer to an array of createInfoCount valid VkGraphicsPipelineCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00522~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00523~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pPipelines must be a pointer to an array of createInfoCount VkPipeline handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00524~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'createInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00525~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)~^~
+VALIDATION_ERROR_00526~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, basePipelineHandle must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00527~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, it must be a valid index into the calling commands pCreateInfos parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00528~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineIndex must be -1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00529~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineHandle must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00530~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, it must be a valid handle to a graphics VkPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00531~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of each element of pStages must be unique' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00532~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of one element of pStages must be VK_SHADER_STAGE_VERTEX_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00533~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of any given element of pStages must not be VK_SHADER_STAGE_COMPUTE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00534~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage, it must include a tessellation evaluation shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00535~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation evaluation shader stage, it must include a tessellation control shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00536~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pTessellationState must not be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00537~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00538~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00539~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00540~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'flags must be a valid combination of VkPipelineCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00541~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pStages must be a pointer to an array of stageCount valid VkPipelineShaderStageCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00542~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pVertexInputState must be a pointer to a valid VkPipelineVertexInputStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00543~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pInputAssemblyState must be a pointer to a valid VkPipelineInputAssemblyStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00544~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pRasterizationState must be a pointer to a valid VkPipelineRasterizationStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00545~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pDynamicState is not NULL, pDynamicState must be a pointer to a valid VkPipelineDynamicStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00546~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00547~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00548~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'stageCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00549~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'Each of basePipelineHandle, layout, and renderPass that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_00550~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)~^~
+VALIDATION_ERROR_00551~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)~^~
+VALIDATION_ERROR_00552~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)~^~
+VALIDATION_ERROR_00553~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pDynamicStates must be a pointer to an array of dynamicStateCount valid VkDynamicState values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)~^~
+VALIDATION_ERROR_00554~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'dynamicStateCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)~^~
+VALIDATION_ERROR_00555~^~Y~^~PipelineInUseDestroyedSignaled~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'All submitted commands that refer to pipeline must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00556~^~U~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If VkAllocationCallbacks were provided when pipeline was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00557~^~U~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If no VkAllocationCallbacks were provided when pipeline was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00558~^~Y~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00559~^~Y~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00560~^~U~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00561~^~U~^~Unknown~^~vkDestroyPipeline~^~For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pipeline is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)~^~
+VALIDATION_ERROR_00562~^~Y~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)~^~
+VALIDATION_ERROR_00563~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pCreateInfo must be a pointer to a valid VkPipelineCacheCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)~^~
+VALIDATION_ERROR_00564~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)~^~
+VALIDATION_ERROR_00565~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pPipelineCache must be a pointer to a VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)~^~
+VALIDATION_ERROR_00566~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, it must be equal to the size of pInitialData, as returned by vkGetPipelineCacheData when pInitialData was originally retrieved' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_00567~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_00568~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_00569~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_00570~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, pInitialData must be a pointer to an array of initialDataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_00571~^~U~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must not appear in the list of source caches' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00572~^~Y~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00573~^~Y~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00574~^~U~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pSrcCaches must be a pointer to an array of srcCacheCount valid VkPipelineCache handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00575~^~U~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'srcCacheCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00576~^~U~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00577~^~Y~^~Unknown~^~vkMergePipelineCaches~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'Each element of pSrcCaches must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)~^~
+VALIDATION_ERROR_00578~^~Y~^~Unknown~^~vkGetPipelineCacheData~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)~^~
+VALIDATION_ERROR_00579~^~Y~^~Unknown~^~vkGetPipelineCacheData~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)~^~
+VALIDATION_ERROR_00580~^~U~^~Unknown~^~vkGetPipelineCacheData~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pDataSize must be a pointer to a size_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)~^~
+VALIDATION_ERROR_00581~^~U~^~Unknown~^~vkGetPipelineCacheData~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If the value referenced by pDataSize is not 0, and pData is not NULL, pData must be a pointer to an array of pDataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)~^~
+VALIDATION_ERROR_00582~^~U~^~Unknown~^~vkGetPipelineCacheData~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pipelineCache must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)~^~
+VALIDATION_ERROR_00583~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If VkAllocationCallbacks were provided when pipelineCache was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00584~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If no VkAllocationCallbacks were provided when pipelineCache was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00585~^~Y~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00586~^~Y~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00587~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00588~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)~^~
+VALIDATION_ERROR_00589~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'The offset member of any given element of pMapEntries must be less than dataSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)~^~
+VALIDATION_ERROR_00590~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'For any given element of pMapEntries, size must be less than or equal to dataSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)~^~
+VALIDATION_ERROR_00591~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'If mapEntryCount is not 0, pMapEntries must be a pointer to an array of mapEntryCount valid VkSpecializationMapEntry structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)~^~
+VALIDATION_ERROR_00592~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'If dataSize is not 0, pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)~^~
+VALIDATION_ERROR_00593~^~U~^~Unknown~^~vkDestroyPipelineCache~^~For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'For a constantID specialization constant declared in a shader, size must match the byte size of the constantID. If the specialization constant is of type boolean, size must be the byte size of VkBool32' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationMapEntry)~^~
+VALIDATION_ERROR_00594~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, the VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00595~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00596~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, pipeline must be a compute pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00597~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline must be a graphics pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00598~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If the variable multisample rate feature is not supported, pipeline is a graphics pipeline, the current subpass has no attachments, and this is not the first call to this function with a graphics pipeline after transitioning to the current subpass, then the sample count specified by this pipeline must match that set in the previous pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00599~^~Y~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00600~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00601~^~Y~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'pipeline must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00602~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00603~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00604~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'Both of commandBuffer, and pipeline must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)~^~
+VALIDATION_ERROR_00605~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnAllocation must be a pointer to a valid user-defined PFN_vkAllocationFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)~^~
+VALIDATION_ERROR_00606~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnReallocation must be a pointer to a valid user-defined PFN_vkReallocationFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)~^~
+VALIDATION_ERROR_00607~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnFree must be a pointer to a valid user-defined PFN_vkFreeFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)~^~
+VALIDATION_ERROR_00608~^~U~^~Unknown~^~vkCmdBindPipeline~^~For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'If either of pfnInternalAllocation or pfnInternalFree is not NULL, both must be valid callbacks' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)~^~
+VALIDATION_ERROR_00609~^~Y~^~Unknown~^~vkGetPhysicalDeviceMemoryProperties~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMemoryProperties)~^~
+VALIDATION_ERROR_00610~^~U~^~Unknown~^~vkGetPhysicalDeviceMemoryProperties~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pMemoryProperties must be a pointer to a VkPhysicalDeviceMemoryProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMemoryProperties)~^~
+VALIDATION_ERROR_00611~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'The number of currently valid memory objects, allocated from device, must be less than VkPhysicalDeviceLimits::maxMemoryAllocationCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)~^~
+VALIDATION_ERROR_00612~^~Y~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)~^~
+VALIDATION_ERROR_00613~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pAllocateInfo must be a pointer to a valid VkMemoryAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)~^~
+VALIDATION_ERROR_00614~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)~^~
+VALIDATION_ERROR_00615~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pMemory must be a pointer to a VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)~^~
+VALIDATION_ERROR_00616~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'allocationSize must be less than or equal to the amount of memory available to the VkMemoryHeap specified by memoryTypeIndex and the calling commands VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)~^~
+VALIDATION_ERROR_00617~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'allocationSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)~^~
+VALIDATION_ERROR_00618~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)~^~
+VALIDATION_ERROR_00619~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationMemoryAllocateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)~^~
+VALIDATION_ERROR_00620~^~Y~^~None~^~vkFreeMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'All submitted commands that refer to memory (via images or buffers) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)~^~
+VALIDATION_ERROR_00621~^~Y~^~Unknown~^~vkFreeMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)~^~
+VALIDATION_ERROR_00622~^~Y~^~Unknown~^~vkFreeMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)~^~
+VALIDATION_ERROR_00623~^~U~^~Unknown~^~vkFreeMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)~^~
+VALIDATION_ERROR_00624~^~U~^~Unknown~^~vkFreeMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If memory is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)~^~
+VALIDATION_ERROR_00625~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must not currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00626~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'offset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00627~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00628~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to the size of the memory minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00629~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00630~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00631~^~Y~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00632~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00633~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'ppData must be a pointer to a pointer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00634~^~U~^~Unknown~^~vkMapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)~^~
+VALIDATION_ERROR_00635~^~Y~^~Unknown~^~vkFlushMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)~^~
+VALIDATION_ERROR_00636~^~U~^~Unknown~^~vkFlushMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pMemoryRanges must be a pointer to an array of memoryRangeCount valid VkMappedMemoryRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)~^~
+VALIDATION_ERROR_00637~^~U~^~Unknown~^~vkFlushMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memoryRangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)~^~
+VALIDATION_ERROR_00638~^~Y~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)~^~
+VALIDATION_ERROR_00639~^~Y~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pMemoryRanges must be a pointer to an array of memoryRangeCount valid VkMappedMemoryRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)~^~
+VALIDATION_ERROR_00640~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memoryRangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)~^~
+VALIDATION_ERROR_00641~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00642~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, offset and size must specify a range contained within the currently mapped range of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00643~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is equal to VK_WHOLE_SIZE, offset must be within the currently mapped range of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00644~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'offset must be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00645~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00646~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'sType must be VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00647~^~U~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00648~^~Y~^~Unknown~^~vkInvalidateMappedMemoryRanges~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)~^~
+VALIDATION_ERROR_00649~^~U~^~Unknown~^~vkUnmapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)~^~
+VALIDATION_ERROR_00650~^~Y~^~Unknown~^~vkUnmapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)~^~
+VALIDATION_ERROR_00651~^~U~^~Unknown~^~vkUnmapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)~^~
+VALIDATION_ERROR_00652~^~U~^~Unknown~^~vkUnmapMemory~^~For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)~^~
+VALIDATION_ERROR_00653~^~U~^~Unknown~^~vkGetDeviceMemoryCommitment~^~For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)~^~
+VALIDATION_ERROR_00654~^~Y~^~Unknown~^~vkGetDeviceMemoryCommitment~^~For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)~^~
+VALIDATION_ERROR_00655~^~Y~^~Unknown~^~vkGetDeviceMemoryCommitment~^~For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)~^~
+VALIDATION_ERROR_00656~^~U~^~Unknown~^~vkGetDeviceMemoryCommitment~^~For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'pCommittedMemoryInBytes must be a pointer to a VkDeviceSize value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)~^~
+VALIDATION_ERROR_00657~^~U~^~Unknown~^~vkGetDeviceMemoryCommitment~^~For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)~^~
+VALIDATION_ERROR_00658~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the flags member of pCreateInfo includes VK_BUFFER_CREATE_SPARSE_BINDING_BIT, creating this VkBuffer must not cause the total required sparse memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)~^~
+VALIDATION_ERROR_00659~^~Y~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)~^~
+VALIDATION_ERROR_00660~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pCreateInfo must be a pointer to a valid VkBufferCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)~^~
+VALIDATION_ERROR_00661~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)~^~
+VALIDATION_ERROR_00662~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pBuffer must be a pointer to a VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)~^~
+VALIDATION_ERROR_00663~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00664~^~Y~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00665~^~Y~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00666~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse bindings feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00667~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse buffer residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00668~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse aliased residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00669~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00670~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00671~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationBufferCreateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00672~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'flags must be a valid combination of VkBufferCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00673~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'usage must be a valid combination of VkBufferUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00674~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00675~^~N~^~None~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)~^~
+VALIDATION_ERROR_00676~^~U~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'All submitted commands that refer to buffer, either directly or via a VkBufferView, must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00677~^~U~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If VkAllocationCallbacks were provided when buffer was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00678~^~U~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If no VkAllocationCallbacks were provided when buffer was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00679~^~Y~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00680~^~Y~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00681~^~U~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00682~^~U~^~Unknown~^~vkDestroyBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If buffer is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)~^~
+VALIDATION_ERROR_00683~^~Y~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)~^~
+VALIDATION_ERROR_00684~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pCreateInfo must be a pointer to a valid VkBufferViewCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)~^~
+VALIDATION_ERROR_00685~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)~^~
+VALIDATION_ERROR_00686~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pView must be a pointer to a VkBufferView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)~^~
+VALIDATION_ERROR_00687~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00688~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'offset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00689~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If range is not equal to VK_WHOLE_SIZE:range must be greater than 0range must be a multiple of the element size of formatrange divided by the element size of format, must be less than or equal to VkPhysicalDeviceLimits::maxTexelBufferElementsthe sum of offset and range must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00690~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00691~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range must be a multiple of the element size of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00692~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range divided by the element size of format, must be less than or equal to VkPhysicalDeviceLimits::maxTexelBufferElements' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00693~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'the sum of offset and range must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00694~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'buffer must have been created with a usage value containing at least one of VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00695~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If buffer was created with usage containing VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, format must be supported for uniform texel buffers, as specified by the VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00696~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00697~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00698~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00699~^~Y~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00700~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_00701~^~Y~^~BufferViewInUseDestroyedSignaled~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'All submitted commands that refer to bufferView must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00702~^~U~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If VkAllocationCallbacks were provided when bufferView was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00703~^~U~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If no VkAllocationCallbacks were provided when bufferView was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00704~^~Y~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00705~^~Y~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00706~^~U~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00707~^~U~^~Unknown~^~vkDestroyBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If bufferView is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)~^~
+VALIDATION_ERROR_00708~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the flags member of pCreateInfo includes VK_IMAGE_CREATE_SPARSE_BINDING_BIT, creating this VkImage must not cause the total required sparse memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)~^~
+VALIDATION_ERROR_00709~^~Y~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)~^~
+VALIDATION_ERROR_00710~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pCreateInfo must be a pointer to a valid VkImageCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)~^~
+VALIDATION_ERROR_00711~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)~^~
+VALIDATION_ERROR_00712~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pImage must be a pointer to a VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)~^~
+VALIDATION_ERROR_00713~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00714~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00715~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'format must not be VK_FORMAT_UNDEFINED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00716~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'The width, height, and depth members of extent must all be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00717~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevels must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00718~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayers must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00719~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, imageType must be VK_IMAGE_TYPE_2D' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00720~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_1D, extent.width must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension1D, or VkImageFormatProperties::maxExtent.width (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00721~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00722~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationImageCreateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00723~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00724~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'imageType must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00725~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00726~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00727~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00728~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00729~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00730~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'sharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00731~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'initialLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_00732~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00733~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'The aspectMask member of pSubresource must only have a single bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00734~^~Y~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00735~^~Y~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00736~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pSubresource must be a pointer to a valid VkImageSubresource structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00737~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pLayout must be a pointer to a VkSubresourceLayout structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00738~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)~^~
+VALIDATION_ERROR_00739~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)~^~
+VALIDATION_ERROR_00740~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)~^~
+VALIDATION_ERROR_00741~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)~^~
+VALIDATION_ERROR_00742~^~U~^~Unknown~^~vkGetImageSubresourceLayout~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)~^~
+VALIDATION_ERROR_00743~^~Y~^~FramebufferImageInUseDestroyedSignaled~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'All submitted commands that refer to image, either directly or via a VkImageView, must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00744~^~U~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If VkAllocationCallbacks were provided when image was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00745~^~U~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If no VkAllocationCallbacks were provided when image was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00746~^~Y~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00747~^~Y~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If image is not VK_NULL_HANDLE, image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00748~^~U~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00749~^~U~^~Unknown~^~vkDestroyImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If image is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)~^~
+VALIDATION_ERROR_00750~^~Y~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)~^~
+VALIDATION_ERROR_00751~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pCreateInfo must be a pointer to a valid VkImageViewCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)~^~
+VALIDATION_ERROR_00752~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)~^~
+VALIDATION_ERROR_00753~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pView must be a pointer to a VkImageView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)~^~
+VALIDATION_ERROR_00754~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was not created with VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT then viewType must not be VK_IMAGE_VIEW_TYPE_CUBE or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00755~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the image cubemap arrays feature is not enabled, viewType must not be VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00756~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the ETC2 texture compression feature is not enabled, format must not be VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or VK_FORMAT_EAC_R11G11_SNORM_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00757~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the ASTC LDR texture compression feature is not enabled, format must not be VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or VK_FORMAT_ASTC_12x12_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00758~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the BC texture compression feature is not enabled, format must not be VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, or VK_FORMAT_BC7_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00759~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR, format must be format that has at least one supported feature bit present in the value of VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00760~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00761~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00762~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00763~^~Y~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00764~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'viewType must be a valid VkImageViewType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00765~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00766~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'components must be a valid VkComponentMapping structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00767~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subresourceRange must be a valid VkImageSubresourceRange structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_00768~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If levelCount is not VK_REMAINING_MIP_LEVELS, (baseMipLevel + levelCount) must be less than or equal to the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)~^~
+VALIDATION_ERROR_00769~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If layerCount is not VK_REMAINING_ARRAY_LAYERS, (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)~^~
+VALIDATION_ERROR_00770~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)~^~
+VALIDATION_ERROR_00771~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)~^~
+VALIDATION_ERROR_00772~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'r must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)~^~
+VALIDATION_ERROR_00773~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'g must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)~^~
+VALIDATION_ERROR_00774~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'b must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)~^~
+VALIDATION_ERROR_00775~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'a must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)~^~
+VALIDATION_ERROR_00776~^~Y~^~ImageViewInUseDestroyedSignaled~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'All submitted commands that refer to imageView must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00777~^~U~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If VkAllocationCallbacks were provided when imageView was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00778~^~U~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If no VkAllocationCallbacks were provided when imageView was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00779~^~Y~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00780~^~Y~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00781~^~U~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00782~^~U~^~Unknown~^~vkDestroyImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If imageView is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)~^~
+VALIDATION_ERROR_00783~^~Y~^~Unknown~^~vkGetBufferMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)~^~
+VALIDATION_ERROR_00784~^~Y~^~Unknown~^~vkGetBufferMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)~^~
+VALIDATION_ERROR_00785~^~U~^~Unknown~^~vkGetBufferMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'pMemoryRequirements must be a pointer to a VkMemoryRequirements structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)~^~
+VALIDATION_ERROR_00786~^~U~^~Unknown~^~vkGetBufferMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)~^~
+VALIDATION_ERROR_00787~^~Y~^~Unknown~^~vkGetImageMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)~^~
+VALIDATION_ERROR_00788~^~Y~^~Unknown~^~vkGetImageMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)~^~
+VALIDATION_ERROR_00789~^~U~^~Unknown~^~vkGetImageMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'pMemoryRequirements must be a pointer to a VkMemoryRequirements structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)~^~
+VALIDATION_ERROR_00790~^~U~^~Unknown~^~vkGetImageMemoryRequirements~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)~^~
+VALIDATION_ERROR_00791~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must not already be backed by a memory object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00792~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must not have been created with any sparse memory binding flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00793~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00794~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00795~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00796~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00797~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00798~^~Y~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00799~^~Y~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00800~^~Y~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00801~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00802~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_00803~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must not already be backed by a memory object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00804~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must not have been created with any sparse memory binding flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00805~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00806~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00807~^~Y~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00808~^~Y~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00809~^~Y~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00810~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00811~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_00812~^~Y~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)~^~
+VALIDATION_ERROR_00813~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pCreateInfo must be a pointer to a valid VkSamplerCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)~^~
+VALIDATION_ERROR_00814~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)~^~
+VALIDATION_ERROR_00815~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pSampler must be a pointer to a VkSampler handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)~^~
+VALIDATION_ERROR_00816~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'The absolute value of mipLodBias must be less than or equal to VkPhysicalDeviceLimits::maxSamplerLodBias' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00817~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If the anisotropic sampling feature is not enabled, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00818~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If anisotropyEnable is VK_TRUE, maxAnisotropy must be between 1.0 and VkPhysicalDeviceLimits::maxSamplerAnisotropy, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00819~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, minFilter and magFilter must be equal' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00820~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, mipmapMode must be VK_SAMPLER_MIPMAP_MODE_NEAREST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00821~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, minLod and maxLod must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00822~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, addressModeU and addressModeV must each be either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00823~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00824~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, compareEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00825~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a valid VkBorderColor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00826~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If the VK_KHR_sampler_mirror_clamp_to_edge extension is not enabled, addressModeU, addressModeV and addressModeW must not be VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00827~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00828~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'sType must be VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00829~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00830~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00831~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'magFilter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00832~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'minFilter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00833~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'mipmapMode must be a valid VkSamplerMipmapMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00834~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeU must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00835~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeV must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00836~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeW must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_00837~^~Y~^~SamplerInUseDestroyedSignaled~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'All submitted commands that refer to sampler must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00838~^~U~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If VkAllocationCallbacks were provided when sampler was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00839~^~U~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If no VkAllocationCallbacks were provided when sampler was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00840~^~Y~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00841~^~Y~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00842~^~U~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00843~^~U~^~Unknown~^~vkDestroySampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If sampler is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)~^~
+VALIDATION_ERROR_00844~^~Y~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)~^~
+VALIDATION_ERROR_00845~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pCreateInfo must be a pointer to a valid VkDescriptorSetLayoutCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)~^~
+VALIDATION_ERROR_00846~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)~^~
+VALIDATION_ERROR_00847~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pSetLayout must be a pointer to a VkDescriptorSetLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)~^~
+VALIDATION_ERROR_00848~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)~^~
+VALIDATION_ERROR_00849~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)~^~
+VALIDATION_ERROR_00850~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)~^~
+VALIDATION_ERROR_00851~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If bindingCount is not 0, pBindings must be a pointer to an array of bindingCount valid VkDescriptorSetLayoutBinding structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)~^~
+VALIDATION_ERROR_00852~^~Y~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount valid VkSampler handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)~^~
+VALIDATION_ERROR_00853~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)~^~
+VALIDATION_ERROR_00854~^~U~^~Unknown~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'descriptorType must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)~^~
+VALIDATION_ERROR_00855~^~U~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If VkAllocationCallbacks were provided when descriptorSetLayout was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00856~^~U~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If no VkAllocationCallbacks were provided when descriptorSetLayout was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00857~^~Y~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00858~^~Y~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorSetLayout is not VK_NULL_HANDLE, descriptorSetLayout must be a valid VkDescriptorSetLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00859~^~U~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00860~^~U~^~Unknown~^~vkDestroyDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorSetLayout is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)~^~
+VALIDATION_ERROR_00861~^~Y~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)~^~
+VALIDATION_ERROR_00862~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pCreateInfo must be a pointer to a valid VkPipelineLayoutCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)~^~
+VALIDATION_ERROR_00863~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)~^~
+VALIDATION_ERROR_00864~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pPipelineLayout must be a pointer to a VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)~^~
+VALIDATION_ERROR_00865~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'setLayoutCount must be less than or equal to VkPhysicalDeviceLimits::maxBoundDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00866~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSamplers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00867~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorUniformBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00868~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00869~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSampledImages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00870~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageImages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00871~^~N~^~None~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'Any two elements of pPushConstantRanges must not include the same stage in stageFlags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00872~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00873~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00874~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00875~^~Y~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If setLayoutCount is not 0, pSetLayouts must be a pointer to an array of setLayoutCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00876~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pushConstantRangeCount is not 0, pPushConstantRanges must be a pointer to an array of pushConstantRangeCount valid VkPushConstantRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)~^~
+VALIDATION_ERROR_00877~^~Y~^~InvalidPushConstants~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00878~^~Y~^~InvalidPushConstants~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00879~^~Y~^~InvalidPushConstants~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00880~^~Y~^~InvalidPushConstants~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be less than or equal to VkPhysicalDeviceLimits::maxPushConstantsSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00881~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00882~^~U~^~Unknown~^~vkCreatePipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'stageFlags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)~^~
+VALIDATION_ERROR_00883~^~U~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If VkAllocationCallbacks were provided when pipelineLayout was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00884~^~U~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If no VkAllocationCallbacks were provided when pipelineLayout was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00885~^~Y~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00886~^~Y~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pipelineLayout is not VK_NULL_HANDLE, pipelineLayout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00887~^~U~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00888~^~U~^~Unknown~^~vkDestroyPipelineLayout~^~For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pipelineLayout is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)~^~
+VALIDATION_ERROR_00889~^~Y~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)~^~
+VALIDATION_ERROR_00890~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pCreateInfo must be a pointer to a valid VkDescriptorPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)~^~
+VALIDATION_ERROR_00891~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)~^~
+VALIDATION_ERROR_00892~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorPool must be a pointer to a VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)~^~
+VALIDATION_ERROR_00893~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'maxSets must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00894~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00895~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00896~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'flags must be a valid combination of VkDescriptorPoolCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00897~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pPoolSizes must be a pointer to an array of poolSizeCount valid VkDescriptorPoolSize structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00898~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'poolSizeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)~^~
+VALIDATION_ERROR_00899~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolSize)~^~
+VALIDATION_ERROR_00900~^~U~^~Unknown~^~vkCreateDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'type must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolSize)~^~
+VALIDATION_ERROR_00901~^~Y~^~None~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00902~^~U~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If VkAllocationCallbacks were provided when descriptorPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00903~^~U~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If no VkAllocationCallbacks were provided when descriptorPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00904~^~Y~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00905~^~Y~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00906~^~U~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00907~^~U~^~Unknown~^~vkDestroyDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If descriptorPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)~^~
+VALIDATION_ERROR_00908~^~Y~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)~^~
+VALIDATION_ERROR_00909~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pAllocateInfo must be a pointer to a valid VkDescriptorSetAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)~^~
+VALIDATION_ERROR_00910~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorSets must be a pointer to an array of pAllocateInfo::descriptorSetCount VkDescriptorSet handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)~^~
+VALIDATION_ERROR_00911~^~Y~^~None~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must not be greater than the number of sets that are currently available for allocation in descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00912~^~Y~^~AllocDescriptorFromEmptyPool~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have enough free descriptor capacity remaining to allocate the descriptor sets of the specified layouts' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00913~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00914~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00915~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00916~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pSetLayouts must be a pointer to an array of descriptorSetCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00917~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00918~^~U~^~Unknown~^~vkAllocateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Both of descriptorPool, and the elements of pSetLayouts must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)~^~
+VALIDATION_ERROR_00919~^~Y~^~InvalidCmdBufferDescriptorSetImageSamplerDestroyed~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All submitted commands that refer to any element of pDescriptorSets must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00920~^~U~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorSets must be a pointer to an array of descriptorSetCount VkDescriptorSet handles, each element of which must either be a valid handle or VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00921~^~U~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Each valid handle in pDescriptorSets must have been allocated from descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00922~^~Y~^~FreeDescriptorFromOneShotPool~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created with the VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00923~^~Y~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00924~^~Y~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00925~^~U~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00926~^~U~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00927~^~U~^~Unknown~^~vkFreeDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Each element of pDescriptorSets that is a valid handle must have been created, allocated, or retrieved from descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)~^~
+VALIDATION_ERROR_00928~^~U~^~Unknown~^~vkResetDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All uses of descriptorPool (via any allocated descriptor sets) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)~^~
+VALIDATION_ERROR_00929~^~Y~^~Unknown~^~vkResetDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)~^~
+VALIDATION_ERROR_00930~^~Y~^~Unknown~^~vkResetDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)~^~
+VALIDATION_ERROR_00931~^~U~^~Unknown~^~vkResetDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)~^~
+VALIDATION_ERROR_00932~^~U~^~Unknown~^~vkResetDescriptorPool~^~For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)~^~
+VALIDATION_ERROR_00933~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)~^~
+VALIDATION_ERROR_00934~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorWriteCount is not 0, pDescriptorWrites must be a pointer to an array of descriptorWriteCount valid VkWriteDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)~^~
+VALIDATION_ERROR_00935~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorCopyCount is not 0, pDescriptorCopies must be a pointer to an array of descriptorCopyCount valid VkCopyDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)~^~
+VALIDATION_ERROR_00936~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding point within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00937~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must match the type of dstBinding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00938~^~Y~^~WriteDescriptorSetIntegrityCheck~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00939~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00940~^~Y~^~InvalidBufferViewObject~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00941~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00942~^~Y~^~SampleDescriptorUpdateError~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was not allocated with a layout that included immutable samplers for dstBinding with descriptorType, the sampler member of any given element of pImageInfo must be a valid VkSampler object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00943~^~Y~^~ImageViewDescriptorUpdateError~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00944~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00945~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00946~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00947~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00948~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxUniformBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00949~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxStorageBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00950~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00951~^~Y~^~DSUsageBitsErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00952~^~N~^~None~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView member of any given element of pImageInfo must have been created with the identity swizzle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00953~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00954~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00955~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00956~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00957~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00958~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of dstSet, and the elements of pTexelBufferView that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)~^~
+VALIDATION_ERROR_00959~^~Y~^~DSBufferInfoErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)~^~
+VALIDATION_ERROR_00960~^~Y~^~DSBufferInfoErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)~^~
+VALIDATION_ERROR_00961~^~Y~^~DSBufferInfoErrors~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be less than or equal to the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)~^~
+VALIDATION_ERROR_00962~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)~^~
+VALIDATION_ERROR_00963~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of imageView, and sampler that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorImageInfo)~^~
+VALIDATION_ERROR_00964~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcBinding must be a valid binding within srcSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00965~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of srcArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by srcBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00966~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00967~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00968~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If srcSet is equal to dstSet, then the source and destination ranges of descriptors must not overlap, where the ranges may include array elements from consecutive bindings as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00969~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00970~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00971~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00972~^~Y~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00973~^~U~^~Unknown~^~vkUpdateDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of dstSet, and srcSet must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)~^~
+VALIDATION_ERROR_00974~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Any given element of pDescriptorSets must have been allocated with a VkDescriptorSetLayout that matches (is the same as, or defined identically to) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00975~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'dynamicOffsetCount must be equal to the total number of dynamic descriptors in pDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00976~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'The sum of firstSet and descriptorSetCount must be less than or equal to VkPipelineLayoutCreateInfo::setLayoutCount provided when layout was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00977~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pipelineBindPoint must be supported by the commandBuffers parent VkCommandPools queue family' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00978~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Any given element of pDynamicOffsets must satisfy the required alignment for the corresponding descriptor bindings descriptor type' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00979~^~Y~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00980~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00981~^~Y~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00982~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pDescriptorSets must be a pointer to an array of descriptorSetCount valid VkDescriptorSet handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00983~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'If dynamicOffsetCount is not 0, pDynamicOffsets must be a pointer to an array of dynamicOffsetCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00984~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00985~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00986~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00987~^~U~^~Unknown~^~vkCmdBindDescriptorSets~^~For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Each of commandBuffer, layout, and the elements of pDescriptorSets must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)~^~
+VALIDATION_ERROR_00988~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must match exactly the shader stages used in layout for the range specified by offset and size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00989~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00990~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00991~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00992~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be less than or equal to VkPhysicalDeviceLimits::maxPushConstantsSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00993~^~Y~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00994~^~Y~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00995~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00996~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00997~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'pValues must be a pointer to an array of size bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00998~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_00999~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_01000~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_01001~^~U~^~Unknown~^~vkCmdPushConstants~^~For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'Both of commandBuffer, and layout must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)~^~
+VALIDATION_ERROR_01002~^~Y~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)~^~
+VALIDATION_ERROR_01003~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pCreateInfo must be a pointer to a valid VkQueryPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)~^~
+VALIDATION_ERROR_01004~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)~^~
+VALIDATION_ERROR_01005~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pQueryPool must be a pointer to a VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)~^~
+VALIDATION_ERROR_01006~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If the pipeline statistics queries feature is not enabled, queryType must not be VK_QUERY_TYPE_PIPELINE_STATISTICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01007~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01008~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'sType must be VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01009~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01010~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01011~^~U~^~Unknown~^~vkCreateQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'queryType must be a valid VkQueryType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)~^~
+VALIDATION_ERROR_01012~^~Y~^~QueryPoolInUseDestroyedSignaled~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'All submitted commands that refer to queryPool must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01013~^~U~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If VkAllocationCallbacks were provided when queryPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01014~^~U~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If no VkAllocationCallbacks were provided when queryPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01015~^~Y~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01016~^~Y~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01017~^~U~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01018~^~U~^~Unknown~^~vkDestroyQueryPool~^~For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)~^~
+VALIDATION_ERROR_01019~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01020~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01021~^~Y~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01022~^~Y~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01023~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01024~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01025~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01026~^~U~^~Unknown~^~vkCmdResetQueryPool~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)~^~
+VALIDATION_ERROR_01027~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must currently not be active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01028~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must be unavailable' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01029~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the precise occlusion queries feature is not enabled, or the queryType used to create queryPool was not VK_QUERY_TYPE_OCCLUSION, flags must not contain VK_QUERY_CONTROL_PRECISE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01030~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must have been created with a queryType that differs from that of any other queries that have been made active, and are currently still active within commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01031~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'query must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01032~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_OCCLUSION, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01033~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate graphics operations, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01034~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate compute operations, the VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01035~^~Y~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01036~^~Y~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01037~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryControlFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01038~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01039~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01040~^~U~^~Unknown~^~vkCmdBeginQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)~^~
+VALIDATION_ERROR_01041~^~U~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must currently be active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01042~^~U~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'query must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01043~^~Y~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01044~^~Y~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01045~^~U~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01046~^~U~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01047~^~U~^~Unknown~^~vkCmdEndQuery~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)~^~
+VALIDATION_ERROR_01048~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01049~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is not set in flags then pData and stride must be multiples of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01050~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is set in flags then pData and stride must be multiples of 8' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01051~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01052~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dataSize must be large enough to contain the result of each query, as described here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01053~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01054~^~Y~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01055~^~Y~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01056~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01057~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryResultFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01058~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dataSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01059~^~U~^~Unknown~^~vkGetQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)~^~
+VALIDATION_ERROR_01060~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01061~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01062~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01063~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is not set in flags then dstOffset and stride must be multiples of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01064~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is set in flags then dstOffset and stride must be multiples of 8' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01065~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must have enough storage, from dstOffset, to contain the result of each query, as described here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01066~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01067~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01068~^~Y~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01069~^~Y~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01070~^~Y~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01071~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryResultFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01072~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01073~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01074~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01075~^~U~^~Unknown~^~vkCmdCopyQueryPoolResults~^~For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Each of commandBuffer, dstBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)~^~
+VALIDATION_ERROR_01076~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The query identified by queryPool and query must be unavailable' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01077~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The command pools queue family must support a non-zero timestampValidBits' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01078~^~Y~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01079~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'pipelineStage must be a valid VkPipelineStageFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01080~^~Y~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01081~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01082~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01083~^~U~^~Unknown~^~vkCmdWriteTimestamp~^~For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)~^~
+VALIDATION_ERROR_01084~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01085~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must specify the layout of the image subresource ranges of image specified in pRanges at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01086~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01087~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The image range of any given element of pRanges must be an image subresource range that is contained within image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01088~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must not have a compressed or depth/stencil format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01089~^~Y~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01090~^~Y~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01091~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01092~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pColor must be a pointer to a valid VkClearColorValue union' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01093~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pRanges must be a pointer to an array of rangeCount valid VkImageSubresourceRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01094~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01095~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01096~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01097~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'rangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01098~^~U~^~Unknown~^~vkCmdClearColorImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'Both of commandBuffer, and image must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)~^~
+VALIDATION_ERROR_01099~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01100~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must specify the layout of the image subresource ranges of image specified in pRanges at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01101~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01102~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The image range of any given element of pRanges must be an image subresource range that is contained within image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01103~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have a depth/stencil format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01104~^~Y~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01105~^~Y~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01106~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01107~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pDepthStencil must be a pointer to a valid VkClearDepthStencilValue structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01108~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pRanges must be a pointer to an array of rangeCount valid VkImageSubresourceRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01109~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01110~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01111~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01112~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'rangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01113~^~U~^~Unknown~^~vkCmdClearDepthStencilImage~^~For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'Both of commandBuffer, and image must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)~^~
+VALIDATION_ERROR_01114~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'If the aspectMask member of any given element of pAttachments contains VK_IMAGE_ASPECT_COLOR_BIT, the colorAttachment member of those elements must refer to a valid color attachment in the current subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01115~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The rectangular region specified by a given element of pRects must be contained within the render area of the current render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01116~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The layers specified by a given element of pRects must be contained within every attachment that pAttachments refers to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01117~^~Y~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01118~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'pAttachments must be a pointer to an array of attachmentCount valid VkClearAttachment structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01119~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'pRects must be a pointer to an array of rectCount VkClearRect structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01120~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01121~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01122~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01123~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'attachmentCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01124~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'rectCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)~^~
+VALIDATION_ERROR_01125~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'If aspectMask includes VK_IMAGE_ASPECT_COLOR_BIT, it must not include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)~^~
+VALIDATION_ERROR_01126~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must not include VK_IMAGE_ASPECT_METADATA_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)~^~
+VALIDATION_ERROR_01127~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)~^~
+VALIDATION_ERROR_01128~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)~^~
+VALIDATION_ERROR_01129~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'clearValue must be a valid VkClearValue union' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)~^~
+VALIDATION_ERROR_01130~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.3. Clear Values' which states 'depth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearDepthStencilValue)~^~
+VALIDATION_ERROR_01131~^~U~^~Unknown~^~vkCmdClearAttachments~^~For more information refer to Vulkan Spec Section '17.3. Clear Values' which states 'depthStencil must be a valid VkClearDepthStencilValue structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearValue)~^~
+VALIDATION_ERROR_01132~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01133~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01134~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01135~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01136~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01137~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01138~^~Y~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01139~^~Y~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01140~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01141~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01142~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01143~^~U~^~Unknown~^~vkCmdFillBuffer~^~For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'Both of commandBuffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)~^~
+VALIDATION_ERROR_01144~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01145~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01146~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01147~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01148~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be less than or equal to 65536' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01149~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01150~^~Y~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01151~^~Y~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01152~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01153~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01154~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01155~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01156~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01157~^~U~^~Unknown~^~vkCmdUpdateBuffer~^~For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'Both of commandBuffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)~^~
+VALIDATION_ERROR_01158~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01159~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The srcOffset member of a given element of pRegions must be less than the size of srcBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01160~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The dstOffset member of a given element of pRegions must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01161~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be less than or equal to the size of srcBuffer minus srcOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01162~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01163~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The union of the source regions, and the union of the destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01164~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01165~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01166~^~Y~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01167~^~Y~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'srcBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01168~^~Y~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01169~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'pRegions must be a pointer to an array of regionCount VkBufferCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01170~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01171~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01172~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01173~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01174~^~U~^~Unknown~^~vkCmdCopyBuffer~^~For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'Each of commandBuffer, dstBuffer, and srcBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)~^~
+VALIDATION_ERROR_01175~^~Y~^~CopyImageSrcSizeExceeded~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01176~^~Y~^~CopyImageDstSizeExceeded~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01177~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01178~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01179~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01180~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01181~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01182~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01183~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01184~^~Y~^~CopyImageFormatSizeMismatch~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The VkFormat of each of srcImage and dstImage must be compatible, as defined below' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01185~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The sample count of srcImage and dstImage must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01186~^~Y~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01187~^~Y~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01188~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01189~^~Y~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01190~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01191~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'pRegions must be a pointer to an array of regionCount valid VkImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01192~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01193~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01194~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01195~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01196~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)~^~
+VALIDATION_ERROR_01197~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01198~^~Y~^~CopyImageLayerCountMismatch~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01199~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01200~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of srcSubresource must specify aspects present in the calling commands srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01201~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of dstSubresource must specify aspects present in the calling commands dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01202~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.x and (extent.width + srcOffset.x) must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01203~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.y and (extent.height + srcOffset.y) must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01204~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.z and (extent.depth + srcOffset.z) must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01205~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.x and (extent.width + dstOffset.x) must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01206~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.y and (extent.height + dstOffset.y) must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01207~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.z and (extent.depth + dstOffset.z) must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01208~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is a compressed format image:all members of srcOffset must be a multiple of the corresponding dimensions of the compressed texel blockextent.width must be a multiple of the compressed texel block width or (extent.width + srcOffset.x) must equal the source image subresource widthextent.height must be a multiple of the compressed texel block height or (extent.height + srcOffset.y) must equal the source image subresource heightextent.depth must be a multiple of the compressed texel block depth or (extent.depth + srcOffset.z) must equal the source image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01209~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'all members of srcOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01210~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.width must be a multiple of the compressed texel block width or (extent.width + srcOffset.x) must equal the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01211~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.height must be a multiple of the compressed texel block height or (extent.height + srcOffset.y) must equal the source image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01212~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.depth must be a multiple of the compressed texel block depth or (extent.depth + srcOffset.z) must equal the source image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01213~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is a compressed format image:all members of dstOffset must be a multiple of the corresponding dimensions of the compressed texel blockextent.width must be a multiple of the compressed texel block width or (extent.width + dstOffset.x) must equal the destination image subresource widthextent.height must be a multiple of the compressed texel block height or (extent.height + dstOffset.y) must equal the destination image subresource heightextent.depth must be a multiple of the compressed texel block depth or (extent.depth + dstOffset.z) must equal the destination image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01214~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'all members of dstOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01215~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.width must be a multiple of the compressed texel block width or (extent.width + dstOffset.x) must equal the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01216~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.height must be a multiple of the compressed texel block height or (extent.height + dstOffset.y) must equal the destination image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01217~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.depth must be a multiple of the compressed texel block depth or (extent.depth + dstOffset.z) must equal the destination image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01218~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset, dstOffset, and extent must respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in Physical Device Enumeration' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01219~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01220~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01221~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01222~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01223~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01224~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states '(baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01225~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01226~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)~^~
+VALIDATION_ERROR_01227~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The buffer region specified by a given element of pRegions must be a region that is contained within srcBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01228~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The image region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01229~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01230~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01231~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01232~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01233~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01234~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01235~^~Y~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01236~^~Y~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01237~^~Y~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01238~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01239~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'pRegions must be a pointer to an array of regionCount valid VkBufferImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01240~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01241~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01242~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01243~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01244~^~U~^~Unknown~^~vkCmdCopyBufferToImage~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'Each of commandBuffer, dstImage, and srcBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)~^~
+VALIDATION_ERROR_01245~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The image region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01246~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The buffer region specified by a given element of pRegions must be a region that is contained within dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01247~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01248~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01249~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01250~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01251~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01252~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01253~^~Y~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01254~^~Y~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01255~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01256~^~Y~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01257~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'pRegions must be a pointer to an array of regionCount valid VkBufferImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01258~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01259~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01260~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01261~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01262~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'Each of commandBuffer, dstBuffer, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)~^~
+VALIDATION_ERROR_01263~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of the calling commands VkImage parameters formats element size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01264~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01265~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferRowLength must be 0, or greater than or equal to the width member of imageExtent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01266~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferImageHeight must be 0, or greater than or equal to the height member of imageExtent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01267~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.x and (imageExtent.width + imageOffset.x) must both be greater than or equal to 0 and less than or equal to the image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01268~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.y and (imageExtent.height + imageOffset.y) must both be greater than or equal to 0 and less than or equal to the image subresource heightIf the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D, then imageOffset.y must be 0 and imageExtent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01269~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.z and (imageExtent.depth + imageOffset.z) must both be greater than or equal to 0 and less than or equal to the image subresource depthIf the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then imageOffset.z must be 0 and imageExtent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01270~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands VkImage parameter is a compressed format image:bufferRowLength must be a multiple of the compressed texel block widthbufferImageHeight must be a multiple of the compressed texel block heightall members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel blockbufferOffset must be a multiple of the compressed texel block size in bytesimageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) must equal the image subresource widthimageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) must equal the image subresource heightimageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) must equal the image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01271~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferRowLength must be a multiple of the compressed texel block width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01272~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferImageHeight must be a multiple of the compressed texel block height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01273~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'all members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01274~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of the compressed texel block size in bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01275~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) must equal the image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01276~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) must equal the image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01277~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) must equal the image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01278~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset, bufferRowLength, bufferImageHeight and all members of imageOffset and imageExtent must respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in Physical Device Enumeration' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01279~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The aspectMask member of imageSubresource must specify aspects present in the calling commands VkImage parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01280~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The aspectMask member of imageSubresource must only have a single bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01281~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands VkImage parameter is of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of imageSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01282~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'When copying to the depth aspect of an image subresource, the data in the source buffer must be in the range [0,1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01283~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01287~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01288~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01289~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The union of all destination regions, specified by the elements of pRegions, must not overlap in memory with any texel that may be sampled during the blit operation' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01290~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must use a format that supports VK_FORMAT_FEATURE_BLIT_SRC_BIT, which is indicated by VkFormatProperties::linearTilingFeatures (for linear tiled images) or VkFormatProperties::optimalTilingFeatures (for optimally tiled images) - as returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01291~^~Y~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01292~^~Y~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01293~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01294~^~Y~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01295~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01296~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'pRegions must be a pointer to an array of regionCount valid VkImageBlit structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01297~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'filter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01298~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01299~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01300~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01301~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01302~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_01303~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01304~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01305~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01306~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of srcSubresource must specify aspects present in the calling commands srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01307~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of dstSubresource must specify aspects present in the calling commands dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01308~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The layerCount member of dstSubresource must be equal to the layerCount member of srcSubresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01309~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].x and srcOffset[1].x must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01310~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].y and srcOffset[1].y must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset[0].y must be 0 and srcOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01311~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].z and srcOffset[1].z must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01312~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].x and dstOffset[1].x must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01313~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].y and dstOffset[1].y must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset[0].y must be 0 and dstOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01314~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].z and dstOffset[1].z must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01315~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01316~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01317~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01318~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01319~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01320~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImage must have a sample count equal to any valid sample count value other than VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01321~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01322~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01323~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01324~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01325~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01326~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If dstImage was created with tiling equal to VK_IMAGE_TILING_LINEAR, dstImage must have been created with a format that supports being a color attachment, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01327~^~Y~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01328~^~Y~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01329~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01330~^~Y~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01331~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01332~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'pRegions must be a pointer to an array of regionCount valid VkImageResolve structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01333~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01334~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01335~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01336~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01337~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_01338~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The aspectMask member of srcSubresource and dstSubresource must only contain VK_IMAGE_ASPECT_COLOR_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01339~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01340~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01341~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01342~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01343~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, primitiveRestartEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01344~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the geometry shaders feature is not enabled, topology must not be any of VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01345~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the tessellation shaders feature is not enabled, topology must not be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01346~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01347~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01348~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01349~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'topology must be a valid VkPrimitiveTopology value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)~^~
+VALIDATION_ERROR_01350~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01351~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The sum of offset and the address of the range of VkDeviceMemory object that is backing buffer, must be a multiple of the type indicated by indexType' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01352~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must have been created with the VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01353~^~Y~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01354~^~Y~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01355~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'indexType must be a valid VkIndexType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01356~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01357~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01358~^~U~^~Unknown~^~vkCmdBindIndexBuffer~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)~^~
+VALIDATION_ERROR_01359~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01360~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01361~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01362~^~Y~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01363~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01364~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01365~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01366~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01367~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01368~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01369~^~Y~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01370~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01371~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01372~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01373~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01374~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01375~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the multi-draw indirect feature is not enabled, drawCount must be 0 or 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01376~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01377~^~Y~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01378~^~Y~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01379~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01380~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01381~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01382~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_01383~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndirectCommand)~^~
+VALIDATION_ERROR_01384~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndirectCommand)~^~
+VALIDATION_ERROR_01385~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01386~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndexedIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01387~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the multi-draw indirect feature is not enabled, drawCount must be 0 or 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01388~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01389~^~Y~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01390~^~Y~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01391~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01392~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01393~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01394~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_01395~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)~^~
+VALIDATION_ERROR_01396~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states '(indexSize * (firstIndex + indexCount) + offset) must be less than or equal to the size of the currently bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexType, and offset are specified via vkCmdBindIndexBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)~^~
+VALIDATION_ERROR_01397~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'vertexBindingDescriptionCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01398~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'vertexAttributeDescriptionCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01399~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'For every binding specified by any given element of pVertexAttributeDescriptions, a VkVertexInputBindingDescription must exist in pVertexBindingDescriptions with the same value of binding' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01400~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pVertexBindingDescriptions must describe distinct binding numbers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01401~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pVertexAttributeDescriptions must describe distinct attribute locations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01402~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01403~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01404~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01405~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'If vertexBindingDescriptionCount is not 0, pVertexBindingDescriptions must be a pointer to an array of vertexBindingDescriptionCount valid VkVertexInputBindingDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01406~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'If vertexAttributeDescriptionCount is not 0, pVertexAttributeDescriptions must be a pointer to an array of vertexAttributeDescriptionCount valid VkVertexInputAttributeDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)~^~
+VALIDATION_ERROR_01407~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)~^~
+VALIDATION_ERROR_01408~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'stride must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindingStride' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)~^~
+VALIDATION_ERROR_01409~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'inputRate must be a valid VkVertexInputRate value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)~^~
+VALIDATION_ERROR_01410~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'location must be less than VkPhysicalDeviceLimits::maxVertexInputAttributes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)~^~
+VALIDATION_ERROR_01411~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)~^~
+VALIDATION_ERROR_01412~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'offset must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributeOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)~^~
+VALIDATION_ERROR_01413~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'format must be allowed as a vertex buffer format, as specified by the VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)~^~
+VALIDATION_ERROR_01414~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)~^~
+VALIDATION_ERROR_01415~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'firstBinding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01416~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'The sum of firstBinding and bindingCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01417~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pOffsets must be less than the size of the corresponding element in pBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01418~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pBuffers must have been created with the VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01419~^~Y~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01420~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pBuffers must be a pointer to an array of bindingCount valid VkBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01421~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pOffsets must be a pointer to an array of bindingCount VkDeviceSize values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01422~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01423~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01424~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'bindingCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01425~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'Both of commandBuffer, and the elements of pBuffers must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)~^~
+VALIDATION_ERROR_01426~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'patchControlPoints must be greater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
+VALIDATION_ERROR_01427~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
+VALIDATION_ERROR_01428~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
+VALIDATION_ERROR_01429~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)~^~
+VALIDATION_ERROR_01430~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the multiple viewports feature is not enabled, viewportCount must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01431~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the multiple viewports feature is not enabled, scissorCount must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01432~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01433~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01434~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount and viewportCount must be identical' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01435~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01436~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01437~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01438~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01439~^~U~^~Unknown~^~vkCmdBindVertexBuffers~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)~^~
+VALIDATION_ERROR_01440~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01441~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'firstViewport must be less than VkPhysicalDeviceLimits::maxViewports' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01442~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The sum of firstViewport and viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01443~^~Y~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01444~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pViewports must be a pointer to an array of viewportCount valid VkViewport structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01445~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01446~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01447~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)~^~
+VALIDATION_ERROR_01448~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'width must be greater than 0.0 and less than or equal to VkPhysicalDeviceLimits::maxViewportDimensions[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01449~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'height must be greater than 0.0 and less than or equal to VkPhysicalDeviceLimits::maxViewportDimensions[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01450~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'x and y must each be between viewportBoundsRange[0] and viewportBoundsRange[1], inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01451~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'x + width must be less than or equal to viewportBoundsRange[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01452~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'y + height must be less than or equal to viewportBoundsRange[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01453~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'minDepth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01454~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'maxDepth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01455~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the depth clamping feature is not enabled, depthClampEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01456~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the non-solid fill modes feature is not enabled, polygonMode must be VK_POLYGON_MODE_FILL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01457~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01458~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL, or a pointer to a valid instance of VkPipelineRasterizationStateRasterizationOrderAMD' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01459~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01460~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'polygonMode must be a valid VkPolygonMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01461~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'cullMode must be a valid combination of VkCullModeFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01462~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'frontFace must be a valid VkFrontFace value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)~^~
+VALIDATION_ERROR_01463~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the sample rate shading feature is not enabled, sampleShadingEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01464~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the alpha to one feature is not enabled, alphaToOneEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01465~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'minSampleShading must be in the range [0,1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01466~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01467~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01468~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01469~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'rasterizationSamples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01470~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If pSampleMask is not NULL, pSampleMask must be a pointer to an array of $/lceil{/mathit{rasterizationSamples} /over 32}/rceil$ VkSampleMask values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)~^~
+VALIDATION_ERROR_01476~^~U~^~Unknown~^~vkCmdSetLineWidth~^~For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)~^~
+VALIDATION_ERROR_01477~^~U~^~Unknown~^~vkCmdSetLineWidth~^~For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'If the wide lines feature is not enabled, lineWidth must be 1.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)~^~
+VALIDATION_ERROR_01478~^~Y~^~Unknown~^~vkCmdSetLineWidth~^~For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)~^~
+VALIDATION_ERROR_01479~^~U~^~Unknown~^~vkCmdSetLineWidth~^~For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)~^~
+VALIDATION_ERROR_01480~^~U~^~Unknown~^~vkCmdSetLineWidth~^~For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)~^~
+VALIDATION_ERROR_01481~^~U~^~Unknown~^~vkCmdSetDepthBias~^~For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)~^~
+VALIDATION_ERROR_01482~^~U~^~Unknown~^~vkCmdSetDepthBias~^~For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)~^~
+VALIDATION_ERROR_01483~^~Y~^~Unknown~^~vkCmdSetDepthBias~^~For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)~^~
+VALIDATION_ERROR_01484~^~U~^~Unknown~^~vkCmdSetDepthBias~^~For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)~^~
+VALIDATION_ERROR_01485~^~U~^~Unknown~^~vkCmdSetDepthBias~^~For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)~^~
+VALIDATION_ERROR_01486~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01487~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'firstScissor must be less than VkPhysicalDeviceLimits::maxViewports' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01488~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The sum of firstScissor and scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01489~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The x and y members of offset must be greater than or equal to 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01490~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'Evaluation of (offset.x + extent.width) must not cause a signed integer addition overflow' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01491~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'Evaluation of (offset.y + extent.height) must not cause a signed integer addition overflow' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01492~^~Y~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01493~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'pScissors must be a pointer to an array of scissorCount VkRect2D structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01494~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01495~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01496~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'scissorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)~^~
+VALIDATION_ERROR_01497~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'If the depth bounds testing feature is not enabled, depthBoundsTestEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01498~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01499~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01500~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01501~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'depthCompareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01502~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'front must be a valid VkStencilOpState structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01503~^~U~^~Unknown~^~vkCmdSetScissor~^~For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'back must be a valid VkStencilOpState structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)~^~
+VALIDATION_ERROR_01504~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01505~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'minDepthBounds must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01506~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'maxDepthBounds must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01507~^~Y~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01508~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01509~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)~^~
+VALIDATION_ERROR_01510~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'failOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)~^~
+VALIDATION_ERROR_01511~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'passOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)~^~
+VALIDATION_ERROR_01512~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'depthFailOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)~^~
+VALIDATION_ERROR_01513~^~U~^~Unknown~^~vkCmdSetDepthBounds~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'compareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)~^~
+VALIDATION_ERROR_01514~^~U~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01515~^~Y~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01516~^~U~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01517~^~U~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01518~^~U~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01519~^~U~^~Unknown~^~vkCmdSetStencilCompareMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)~^~
+VALIDATION_ERROR_01520~^~U~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01521~^~Y~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01522~^~U~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01523~^~U~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01524~^~U~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01525~^~U~^~Unknown~^~vkCmdSetStencilWriteMask~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)~^~
+VALIDATION_ERROR_01526~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01527~^~Y~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01528~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01529~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01530~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01531~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)~^~
+VALIDATION_ERROR_01532~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the independent blending feature is not enabled, all elements of pAttachments must be identical' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01533~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the logic operations feature is not enabled, logicOpEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01534~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01535~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01536~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01537~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01538~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkPipelineColorBlendAttachmentState structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)~^~
+VALIDATION_ERROR_01539~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, srcColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01540~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, dstColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01541~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, srcAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01542~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, dstAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01543~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'srcColorBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01544~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'dstColorBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01545~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'colorBlendOp must be a valid VkBlendOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01546~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'srcAlphaBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01547~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'dstAlphaBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01548~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'alphaBlendOp must be a valid VkBlendOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01549~^~U~^~Unknown~^~vkCmdSetStencilReference~^~For more information refer to Vulkan Spec Section '26.1. Blending' which states 'colorWriteMask must be a valid combination of VkColorComponentFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)~^~
+VALIDATION_ERROR_01550~^~U~^~Unknown~^~vkCmdSetBlendConstants~^~For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)~^~
+VALIDATION_ERROR_01551~^~Y~^~Unknown~^~vkCmdSetBlendConstants~^~For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)~^~
+VALIDATION_ERROR_01552~^~U~^~Unknown~^~vkCmdSetBlendConstants~^~For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)~^~
+VALIDATION_ERROR_01553~^~U~^~Unknown~^~vkCmdSetBlendConstants~^~For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)~^~
+VALIDATION_ERROR_01554~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'x must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01555~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'y must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01556~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'z must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[2]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01557~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01558~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01559~^~Y~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01560~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01561~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01562~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_01563~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01564~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01565~^~Y~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01566~^~Y~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01567~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01568~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01569~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01570~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_01571~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'x must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)~^~
+VALIDATION_ERROR_01572~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'y must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)~^~
+VALIDATION_ERROR_01573~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'z must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[2]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)~^~
+VALIDATION_ERROR_01600~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'samples must be a bit value that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, and usage equal to those in this command and flags equal to the value that is set in VkImageCreateInfo::flags when the image is created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01601~^~Y~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01602~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01603~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01604~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01605~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01606~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01607~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01608~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01609~^~U~^~Unknown~^~vkGetPhysicalDeviceSparseImageFormatProperties~^~For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkSparseImageFormatProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)~^~
+VALIDATION_ERROR_01610~^~Y~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)~^~
+VALIDATION_ERROR_01611~^~Y~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)~^~
+VALIDATION_ERROR_01612~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'pSparseMemoryRequirementCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)~^~
+VALIDATION_ERROR_01613~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'If the value referenced by pSparseMemoryRequirementCount is not 0, and pSparseMemoryRequirements is not NULL, pSparseMemoryRequirements must be a pointer to an array of pSparseMemoryRequirementCount VkSparseImageMemoryRequirements structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)~^~
+VALIDATION_ERROR_01614~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)~^~
+VALIDATION_ERROR_01615~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory and memoryOffset must match the memory requirements of the resource, as described in section Section 11.6, Resource Memory Association' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01616~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must not have been created with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01617~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01618~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'resourceOffset must be less than the size of the resource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01619~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be less than or equal to the size of the resource minus resourceOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01620~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01621~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01622~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01623~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'flags must be a valid combination of VkSparseMemoryBindFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)~^~
+VALIDATION_ERROR_01624~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)~^~
+VALIDATION_ERROR_01625~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)~^~
+VALIDATION_ERROR_01626~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)~^~
+VALIDATION_ERROR_01627~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'For any given element of pBinds, if the flags member of that element contains VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range defined must be within the mip tail region of the metadata aspect of image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)~^~
+VALIDATION_ERROR_01628~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)~^~
+VALIDATION_ERROR_01629~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)~^~
+VALIDATION_ERROR_01630~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)~^~
+VALIDATION_ERROR_01631~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)~^~
+VALIDATION_ERROR_01632~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseImageMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)~^~
+VALIDATION_ERROR_01633~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)~^~
+VALIDATION_ERROR_01634~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If the sparse aliased residency feature is not enabled, and if any other resources are bound to ranges of memory, the range of memory being bound must not overlap with those bound ranges' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01635~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'memory and memoryOffset must match the memory requirements of the calling commands image, as described in section Section 11.6, Resource Memory Association' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01636~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'subresource must be a valid image subresource for image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01637~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.x must be a multiple of the sparse image block width (VkSparseImageFormatProperties::imageGranularity.width) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01638~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.width must either be a multiple of the sparse image block width of the image, or else extent.width + offset.x must equal the width of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01639~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.y must be a multiple of the sparse image block height (VkSparseImageFormatProperties::imageGranularity.height) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01640~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.height must either be a multiple of the sparse image block height of the image, or else extent.height + offset.y must equal the height of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01641~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.z must be a multiple of the sparse image block depth (VkSparseImageFormatProperties::imageGranularity.depth) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01642~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.depth must either be a multiple of the sparse image block depth of the image, or else extent.depth + offset.z must equal the depth of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01643~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'subresource must be a valid VkImageSubresource structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01644~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01645~^~U~^~Unknown~^~vkGetImageSparseMemoryRequirements~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'flags must be a valid combination of VkSparseMemoryBindFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)~^~
+VALIDATION_ERROR_01646~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'fence must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01647~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'fence must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01648~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01649~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If bindInfoCount is not 0, pBindInfo must be a pointer to an array of bindInfoCount valid VkBindSparseInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01650~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01651~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'The queue must support sparse binding operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01652~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)~^~
+VALIDATION_ERROR_01653~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'sType must be VK_STRUCTURE_TYPE_BIND_SPARSE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01654~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01655~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If waitSemaphoreCount is not 0, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01656~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If bufferBindCount is not 0, pBufferBinds must be a pointer to an array of bufferBindCount valid VkSparseBufferMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01657~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If imageOpaqueBindCount is not 0, pImageOpaqueBinds must be a pointer to an array of imageOpaqueBindCount valid VkSparseImageOpaqueMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01658~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If imageBindCount is not 0, pImageBinds must be a pointer to an array of imageBindCount valid VkSparseImageMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01659~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If signalSemaphoreCount is not 0, pSignalSemaphores must be a pointer to an array of signalSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01660~^~U~^~Unknown~^~vkQueueBindSparse~^~For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'Both of the elements of pSignalSemaphores, and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)~^~
+VALIDATION_ERROR_01665~^~U~^~Unknown~^~vkEnumerateInstanceLayerProperties~^~For more information refer to Vulkan Spec Section '30.1. Layers' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceLayerProperties)~^~
+VALIDATION_ERROR_01666~^~U~^~Unknown~^~vkEnumerateInstanceLayerProperties~^~For more information refer to Vulkan Spec Section '30.1. Layers' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkLayerProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceLayerProperties)~^~
+VALIDATION_ERROR_01667~^~U~^~Unknown~^~vkEnumerateDeviceLayerProperties~^~For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)~^~
+VALIDATION_ERROR_01668~^~U~^~Unknown~^~vkEnumerateDeviceLayerProperties~^~For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)~^~
+VALIDATION_ERROR_01669~^~U~^~Unknown~^~vkEnumerateDeviceLayerProperties~^~For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkLayerProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)~^~
+VALIDATION_ERROR_01670~^~U~^~Unknown~^~vkEnumerateInstanceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, it must be the name of a layer returned by vkEnumerateInstanceLayerProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)~^~
+VALIDATION_ERROR_01671~^~U~^~Unknown~^~vkEnumerateInstanceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, pLayerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)~^~
+VALIDATION_ERROR_01672~^~U~^~Unknown~^~vkEnumerateInstanceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)~^~
+VALIDATION_ERROR_01673~^~U~^~Unknown~^~vkEnumerateInstanceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkExtensionProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)~^~
+VALIDATION_ERROR_01674~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, it must be the name of a layer returned by vkEnumerateDeviceLayerProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
+VALIDATION_ERROR_01675~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
+VALIDATION_ERROR_01676~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, pLayerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
+VALIDATION_ERROR_01677~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
+VALIDATION_ERROR_01679~^~Y~^~Unknown~^~vkGetPhysicalDeviceFeatures~^~For more information refer to Vulkan Spec Section '31.1. Features' which states 'pFeatures must be a pointer to a VkPhysicalDeviceFeatures structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFeatures)~^~
+VALIDATION_ERROR_01680~^~U~^~Unknown~^~vkGetPhysicalDeviceFeatures~^~For more information refer to Vulkan Spec Section '31.1. Features' which states 'If any member of this structure is VK_FALSE, as returned by vkGetPhysicalDeviceFeatures, then it must be VK_FALSE when passed as part of the VkDeviceCreateInfo struct when creating a device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#features-features-inheritedQueries)~^~
+VALIDATION_ERROR_01683~^~Y~^~Unknown~^~vkGetPhysicalDeviceFormatProperties~^~For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)~^~
+VALIDATION_ERROR_01684~^~U~^~Unknown~^~vkGetPhysicalDeviceFormatProperties~^~For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)~^~
+VALIDATION_ERROR_01685~^~U~^~Unknown~^~vkGetPhysicalDeviceFormatProperties~^~For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'pFormatProperties must be a pointer to a VkFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)~^~
+VALIDATION_ERROR_01686~^~Y~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01687~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01688~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01689~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01690~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01691~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01692~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01693~^~U~^~Unknown~^~vkGetPhysicalDeviceImageFormatProperties~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'pImageFormatProperties must be a pointer to a VkImageFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)~^~
+VALIDATION_ERROR_01694~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'sType must be VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01695~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01696~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireSyncs must be a pointer to an array of acquireCount valid VkDeviceMemory handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01697~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireKeys must be a pointer to an array of acquireCount uint64_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01698~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireTimeoutMilliseconds must be a pointer to an array of acquireCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01699~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If releaseCount is not 0, pReleaseSyncs must be a pointer to an array of releaseCount valid VkDeviceMemory handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01700~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If releaseCount is not 0, pReleaseKeys must be a pointer to an array of releaseCount uint64_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01701~^~U~^~Unknown~^~vkQueueSubmit~^~For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Both of the elements of pAcquireSyncs, and the elements of pReleaseSyncs that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)~^~
+VALIDATION_ERROR_01702~^~U~^~Unknown~^~vkCmdBeginRenderPass~^~For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be compatible with the renderPass member of the VkFramebufferCreateInfo structure specified when creating framebuffer.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)~^~
+VALIDATION_ERROR_01703~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'At least one of image and buffer must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01704~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, the image must have been created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01705~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, the buffer must have been created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01706~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01707~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01708~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01709~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01710~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01711~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01712~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'Both of buffer, and image that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01713~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01714~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01715~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01716~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)~^~
+VALIDATION_ERROR_01717~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)~^~
+VALIDATION_ERROR_01718~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)~^~
+VALIDATION_ERROR_01719~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pAttributes must be a pointer to a valid SECURITY_ATTRIBUTES value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)~^~
+VALIDATION_ERROR_01720~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)~^~
+VALIDATION_ERROR_01721~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)~^~
+VALIDATION_ERROR_01722~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)~^~
+VALIDATION_ERROR_01723~^~U~^~Unknown~^~vkAllocateMemory~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)~^~
+VALIDATION_ERROR_01724~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a flag specified in VkExportMemoryAllocateInfoNV::handleTypes when allocating memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01725~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01726~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01727~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01728~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01729~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pHandle must be a pointer to a HANDLE value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01730~^~U~^~Unknown~^~vkGetMemoryWin32HandleNV~^~For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)~^~
+VALIDATION_ERROR_01731~^~U~^~Unknown~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If dedicatedAllocation is VK_TRUE, VkBufferCreateInfo::flags must not include VK_BUFFER_CREATE_SPARSE_BINDING_BIT, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)~^~
+VALIDATION_ERROR_01732~^~U~^~Unknown~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)~^~
+VALIDATION_ERROR_01733~^~U~^~Unknown~^~vkCreateBuffer~^~For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)~^~
+VALIDATION_ERROR_01734~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If dedicatedAllocation is VK_TRUE, VkImageCreateInfo::flags must not include VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)~^~
+VALIDATION_ERROR_01735~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)~^~
+VALIDATION_ERROR_01736~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)~^~
+VALIDATION_ERROR_01737~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)~^~
+VALIDATION_ERROR_01738~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)~^~
+VALIDATION_ERROR_01739~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'handleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)~^~
+VALIDATION_ERROR_01740~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'handleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)~^~
+VALIDATION_ERROR_01741~^~U~^~Unknown~^~vkCreateSampler~^~For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If either magFilter or minFilter is VK_FILTER_CUBIC_IMG, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)~^~
+VALIDATION_ERROR_01742~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01743~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01744~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01745~^~U~^~Unknown~^~vkCmdCopyImage~^~For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)~^~
+VALIDATION_ERROR_01746~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D, then imageOffset.y must be 0 and imageExtent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01747~^~U~^~Unknown~^~vkCmdCopyImageToBuffer~^~For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then imageOffset.z must be 0 and imageExtent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)~^~
+VALIDATION_ERROR_01748~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset[0].y must be 0 and srcOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01749~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01750~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset[0].y must be 0 and dstOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01751~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)~^~
+VALIDATION_ERROR_01752~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.x and (extent.width + srcOffset.x) must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01753~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.y and (extent.height + srcOffset.y) must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01754~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01755~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.z and (extent.depth + srcOffset.z) must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01756~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01757~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.x and (extent.width + dstOffset.x) must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01758~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.y and (extent.height + dstOffset.y) must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01759~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01760~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.z and (extent.depth + dstOffset.z) must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01761~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)~^~
+VALIDATION_ERROR_01762~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01763~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_01764~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01765~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_01766~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01767~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01768~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01769~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If maxDrawCount is greater than or equal to 1, (stride  (maxDrawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01770~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01771~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01772~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01773~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01774~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01775~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01776~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01777~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_01778~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01779~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01780~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01781~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If maxDrawCount is greater than or equal to 1, (stride  (maxDrawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01782~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01783~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01784~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01785~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01786~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01787~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01788~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01789~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_01790~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the VK_AMD_negative_viewport_height extension is enabled, height can also be negative.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)~^~
+VALIDATION_ERROR_01791~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)~^~
+VALIDATION_ERROR_01792~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)~^~
+VALIDATION_ERROR_01793~^~U~^~Unknown~^~vkCmdSetViewport~^~For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'rasterizationOrder must be a valid VkRasterizationOrderAMD value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)~^~
+VALIDATION_ERROR_01794~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)~^~
+VALIDATION_ERROR_01795~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pCreateInfo must be a pointer to a valid VkAndroidSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)~^~
+VALIDATION_ERROR_01796~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)~^~
+VALIDATION_ERROR_01797~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)~^~
+VALIDATION_ERROR_01798~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'sType must be VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01799~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01800~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01801~^~U~^~Unknown~^~vkCreateAndroidSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'window must be a pointer to a ANativeWindow value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01802~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)~^~
+VALIDATION_ERROR_01803~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pCreateInfo must be a pointer to a valid VkMirSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)~^~
+VALIDATION_ERROR_01804~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)~^~
+VALIDATION_ERROR_01805~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)~^~
+VALIDATION_ERROR_01806~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'sType must be VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01807~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01808~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01809~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'connection must be a pointer to a MirConnection value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01810~^~U~^~Unknown~^~vkCreateMirSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'mirSurface must be a pointer to a MirSurface value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01811~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)~^~
+VALIDATION_ERROR_01812~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pCreateInfo must be a pointer to a valid VkWaylandSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)~^~
+VALIDATION_ERROR_01813~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)~^~
+VALIDATION_ERROR_01814~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)~^~
+VALIDATION_ERROR_01815~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'sType must be VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01816~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01817~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01818~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'display must be a pointer to a wl_display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01819~^~U~^~Unknown~^~vkCreateWaylandSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'surface must be a pointer to a wl_surface value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01820~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)~^~
+VALIDATION_ERROR_01821~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pCreateInfo must be a pointer to a valid VkWin32SurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)~^~
+VALIDATION_ERROR_01822~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)~^~
+VALIDATION_ERROR_01823~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)~^~
+VALIDATION_ERROR_01824~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'sType must be VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01825~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01826~^~U~^~Unknown~^~vkCreateWin32SurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01827~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)~^~
+VALIDATION_ERROR_01828~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pCreateInfo must be a pointer to a valid VkXcbSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)~^~
+VALIDATION_ERROR_01829~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)~^~
+VALIDATION_ERROR_01830~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)~^~
+VALIDATION_ERROR_01831~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'sType must be VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01832~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01833~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01834~^~U~^~Unknown~^~vkCreateXcbSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'connection must be a pointer to a xcb_connection_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01836~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)~^~
+VALIDATION_ERROR_01837~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pCreateInfo must be a pointer to a valid VkXlibSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)~^~
+VALIDATION_ERROR_01838~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)~^~
+VALIDATION_ERROR_01839~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)~^~
+VALIDATION_ERROR_01840~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'sType must be VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01841~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01842~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01843~^~U~^~Unknown~^~vkCreateXlibSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'dpy must be a pointer to a Display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01844~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'All VkSwapchainKHR objects created for surface must have been destroyed prior to destroying surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01845~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If VkAllocationCallbacks were provided when surface was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01846~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If no VkAllocationCallbacks were provided when surface was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01847~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01848~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If surface is not VK_NULL_HANDLE, surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01849~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01850~^~U~^~Unknown~^~vkDestroySurfaceKHR~^~For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If surface is a valid handle, it must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)~^~
+VALIDATION_ERROR_01851~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
+VALIDATION_ERROR_01852~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
+VALIDATION_ERROR_01853~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)~^~
+VALIDATION_ERROR_01854~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
+VALIDATION_ERROR_01855~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
+VALIDATION_ERROR_01856~^~U~^~Unknown~^~vkGetPhysicalDeviceDisplayPlanePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPlanePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)~^~
+VALIDATION_ERROR_01857~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'planeIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
+VALIDATION_ERROR_01858~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
+VALIDATION_ERROR_01859~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pDisplayCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
+VALIDATION_ERROR_01860~^~U~^~Unknown~^~vkGetDisplayPlaneSupportedDisplaysKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pDisplayCount is not 0, and pDisplays is not NULL, pDisplays must be a pointer to an array of pDisplayCount VkDisplayKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)~^~
+VALIDATION_ERROR_01861~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01862~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01863~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01864~^~U~^~Unknown~^~vkGetDisplayModePropertiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayModePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)~^~
+VALIDATION_ERROR_01865~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01866~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01867~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pCreateInfo must be a pointer to a valid VkDisplayModeCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01868~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01869~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pMode must be a pointer to a VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)~^~
+VALIDATION_ERROR_01870~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'The width and height members of the visibleRegion member of parameters must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~
+VALIDATION_ERROR_01871~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'The refreshRate member of parameters must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~
+VALIDATION_ERROR_01872~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~
+VALIDATION_ERROR_01873~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~
+VALIDATION_ERROR_01874~^~U~^~Unknown~^~vkCreateDisplayModeKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)~^~
+VALIDATION_ERROR_01875~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
+VALIDATION_ERROR_01876~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'mode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
+VALIDATION_ERROR_01877~^~U~^~Unknown~^~vkGetDisplayPlaneCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pCapabilities must be a pointer to a VkDisplayPlaneCapabilitiesKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)~^~
+VALIDATION_ERROR_01878~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~
+VALIDATION_ERROR_01879~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pCreateInfo must be a pointer to a valid VkDisplaySurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~
+VALIDATION_ERROR_01880~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~
+VALIDATION_ERROR_01881~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)~^~
+VALIDATION_ERROR_01882~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'planeIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01883~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01884~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01885~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01886~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'displayMode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01887~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'transform must be a valid VkSurfaceTransformFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01888~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'alphaMode must be a valid VkDisplayPlaneAlphaFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_01889~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceSupportKHR~^~For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)~^~
+VALIDATION_ERROR_01890~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceSupportKHR~^~For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)~^~
+VALIDATION_ERROR_01891~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceSupportKHR~^~For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)~^~
+VALIDATION_ERROR_01892~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceSupportKHR~^~For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'pSupported must be a pointer to a VkBool32 value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)~^~
+VALIDATION_ERROR_01893~^~U~^~Unknown~^~vkGetPhysicalDeviceMirPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)~^~
+VALIDATION_ERROR_01894~^~U~^~Unknown~^~vkGetPhysicalDeviceMirPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)~^~
+VALIDATION_ERROR_01895~^~U~^~Unknown~^~vkGetPhysicalDeviceMirPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'connection must be a pointer to a MirConnection value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)~^~
+VALIDATION_ERROR_01896~^~U~^~Unknown~^~vkGetPhysicalDeviceWaylandPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)~^~
+VALIDATION_ERROR_01897~^~U~^~Unknown~^~vkGetPhysicalDeviceWaylandPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)~^~
+VALIDATION_ERROR_01898~^~U~^~Unknown~^~vkGetPhysicalDeviceWaylandPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'display must be a pointer to a wl_display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)~^~
+VALIDATION_ERROR_01899~^~U~^~Unknown~^~vkGetPhysicalDeviceWin32PresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.4. Win32 Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWin32PresentationSupportKHR)~^~
+VALIDATION_ERROR_01900~^~U~^~Unknown~^~vkGetPhysicalDeviceWin32PresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.4. Win32 Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWin32PresentationSupportKHR)~^~
+VALIDATION_ERROR_01901~^~U~^~Unknown~^~vkGetPhysicalDeviceXcbPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)~^~
+VALIDATION_ERROR_01902~^~U~^~Unknown~^~vkGetPhysicalDeviceXcbPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)~^~
+VALIDATION_ERROR_01903~^~U~^~Unknown~^~vkGetPhysicalDeviceXcbPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'connection must be a pointer to a xcb_connection_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)~^~
+VALIDATION_ERROR_01904~^~U~^~Unknown~^~vkGetPhysicalDeviceXlibPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)~^~
+VALIDATION_ERROR_01905~^~U~^~Unknown~^~vkGetPhysicalDeviceXlibPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)~^~
+VALIDATION_ERROR_01906~^~U~^~Unknown~^~vkGetPhysicalDeviceXlibPresentationSupportKHR~^~For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'dpy must be a pointer to a Display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)~^~
+VALIDATION_ERROR_01907~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)~^~
+VALIDATION_ERROR_01908~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)~^~
+VALIDATION_ERROR_01909~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceCapabilitiesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pSurfaceCapabilities must be a pointer to a VkSurfaceCapabilitiesKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)~^~
+VALIDATION_ERROR_01910~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceFormatsKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)~^~
+VALIDATION_ERROR_01911~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceFormatsKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)~^~
+VALIDATION_ERROR_01912~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceFormatsKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pSurfaceFormatCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)~^~
+VALIDATION_ERROR_01913~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfaceFormatsKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'If the value referenced by pSurfaceFormatCount is not 0, and pSurfaceFormats is not NULL, pSurfaceFormats must be a pointer to an array of pSurfaceFormatCount VkSurfaceFormatKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)~^~
+VALIDATION_ERROR_01914~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfacePresentModesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)~^~
+VALIDATION_ERROR_01915~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfacePresentModesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)~^~
+VALIDATION_ERROR_01916~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfacePresentModesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pPresentModeCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)~^~
+VALIDATION_ERROR_01917~^~U~^~Unknown~^~vkGetPhysicalDeviceSurfacePresentModesKHR~^~For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'If the value referenced by pPresentModeCount is not 0, and pPresentModes is not NULL, pPresentModes must be a pointer to an array of pPresentModeCount VkPresentModeKHR values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)~^~
+VALIDATION_ERROR_01918~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)~^~
+VALIDATION_ERROR_01919~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pCreateInfo must be a pointer to a valid VkSwapchainCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)~^~
+VALIDATION_ERROR_01920~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)~^~
+VALIDATION_ERROR_01921~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchain must be a pointer to a VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)~^~
+VALIDATION_ERROR_01922~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'surface must be a surface that is supported by the device as determined using vkGetPhysicalDeviceSurfaceSupportKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01923~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01924~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01925~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01926~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01927~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageFormat must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01928~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageColorSpace must be a valid VkColorSpaceKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01929~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01930~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01931~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageSharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01932~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'preTransform must be a valid VkSurfaceTransformFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01933~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'compositeAlpha must be a valid VkCompositeAlphaFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01934~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'presentMode must be a valid VkPresentModeKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01935~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If oldSwapchain is not VK_NULL_HANDLE, oldSwapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01936~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If oldSwapchain is a valid handle, it must have been created, allocated, or retrieved from surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_01937~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'All uses of presentable images acquired from swapchain must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01938~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If VkAllocationCallbacks were provided when swapchain was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01939~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If no VkAllocationCallbacks were provided when swapchain was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01940~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01941~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If swapchain is not VK_NULL_HANDLE, swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01942~^~U~^~Unknown~^~vkDestroySwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)~^~
+VALIDATION_ERROR_01943~^~U~^~Unknown~^~vkCreateSharedSwapchainsKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)~^~
+VALIDATION_ERROR_01944~^~U~^~Unknown~^~vkCreateSharedSwapchainsKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pCreateInfos must be a pointer to an array of swapchainCount valid VkSwapchainCreateInfoKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)~^~
+VALIDATION_ERROR_01945~^~U~^~Unknown~^~vkCreateSharedSwapchainsKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)~^~
+VALIDATION_ERROR_01946~^~U~^~Unknown~^~vkCreateSharedSwapchainsKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchains must be a pointer to an array of swapchainCount VkSwapchainKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)~^~
+VALIDATION_ERROR_01947~^~U~^~Unknown~^~vkCreateSharedSwapchainsKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchainCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)~^~
+VALIDATION_ERROR_01948~^~U~^~Unknown~^~vkGetSwapchainImagesKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)~^~
+VALIDATION_ERROR_01949~^~U~^~Unknown~^~vkGetSwapchainImagesKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)~^~
+VALIDATION_ERROR_01950~^~U~^~Unknown~^~vkGetSwapchainImagesKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchainImageCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)~^~
+VALIDATION_ERROR_01951~^~U~^~Unknown~^~vkGetSwapchainImagesKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If the value referenced by pSwapchainImageCount is not 0, and pSwapchainImages is not NULL, pSwapchainImages must be a pointer to an array of pSwapchainImageCount VkImage handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)~^~
+VALIDATION_ERROR_01952~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is not VK_NULL_HANDLE it must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01953~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is not VK_NULL_HANDLE it must be unsignaled and must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01954~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01955~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01956~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01957~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01958~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pImageIndex must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01959~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01960~^~U~^~Unknown~^~vkAcquireNextImageKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)~^~
+VALIDATION_ERROR_01961~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of pSwapchains member of pPresentInfo must be a swapchain that is created for a surface for which presentation is supported from queue as determined using a call to vkGetPhysicalDeviceSurfaceSupportKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)~^~
+VALIDATION_ERROR_01962~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)~^~
+VALIDATION_ERROR_01963~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pPresentInfo must be a pointer to a valid VkPresentInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)~^~
+VALIDATION_ERROR_01964~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01965~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of VkSemaphore in pWaitSemaphores must refer to a prior signal of that VkSemaphore that will not be consumed by any other wait on that semaphore' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01966~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_PRESENT_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01967~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01968~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If waitSemaphoreCount is not 0, and pWaitSemaphores is not NULL, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01969~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchains must be a pointer to an array of swapchainCount valid VkSwapchainKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01970~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pImageIndices must be a pointer to an array of swapchainCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01971~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pResults is not NULL, pResults must be a pointer to an array of swapchainCount VkResult values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01972~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchainCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)~^~
+VALIDATION_ERROR_01973~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'srcRect must specify a rectangular region that is a subset of the image being presented' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)~^~
+VALIDATION_ERROR_01974~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'dstRect must specify a rectangular region that is a subset of the visibleRegion parameter of the display mode the swapchain being presented uses' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)~^~
+VALIDATION_ERROR_01975~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If the persistentContent member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display the present operation targets then persistent must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)~^~
+VALIDATION_ERROR_01976~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)~^~
+VALIDATION_ERROR_01977~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)~^~
+VALIDATION_ERROR_01978~^~U~^~Unknown~^~vkEnumerateDeviceExtensionProperties~^~For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkExtensionProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)~^~
+VALIDATION_ERROR_01979~^~U~^~Unknown~^~vkGetPhysicalDeviceFeatures~^~For more information refer to Vulkan Spec Section '31.1. Features' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFeatures)~^~
+VALIDATION_ERROR_01980~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01981~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01982~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01983~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01984~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01985~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01986~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01987~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01988~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalHandleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01989~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalHandleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01990~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'pExternalImageFormatProperties must be a pointer to a VkExternalImageFormatPropertiesNV structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01991~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'imageFormatProperties must be a valid VkImageFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01992~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalMemoryFeatures must be a valid combination of VkExternalMemoryFeatureFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01993~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalMemoryFeatures must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01994~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'exportFromImportedHandleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01995~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'exportFromImportedHandleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01996~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'compatibleHandleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01997~^~U~^~Unknown~^~vkGetPhysicalDeviceExternalImageFormatPropertiesNV~^~For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'compatibleHandleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)~^~
+VALIDATION_ERROR_01998~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNameInfo.object must be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)~^~
+VALIDATION_ERROR_01999~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)~^~
+VALIDATION_ERROR_02000~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNameInfo must be a pointer to a VkDebugMarkerObjectNameInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)~^~
+VALIDATION_ERROR_02001~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)~^~
+VALIDATION_ERROR_02002~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)~^~
+VALIDATION_ERROR_02003~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)~^~
+VALIDATION_ERROR_02004~^~U~^~Unknown~^~vkDebugMarkerSetObjectNameEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pObjectName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)~^~
+VALIDATION_ERROR_02005~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo.object must be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)~^~
+VALIDATION_ERROR_02006~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo.tagName must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)~^~
+VALIDATION_ERROR_02007~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)~^~
+VALIDATION_ERROR_02008~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo must be a pointer to a VkDebugMarkerObjectTagInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)~^~
+VALIDATION_ERROR_02009~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)~^~
+VALIDATION_ERROR_02010~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)~^~
+VALIDATION_ERROR_02011~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)~^~
+VALIDATION_ERROR_02012~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTag must be a pointer to an array of tagSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)~^~
+VALIDATION_ERROR_02013~^~U~^~Unknown~^~vkDebugMarkerSetObjectTagEXT~^~For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'tagSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)~^~
+VALIDATION_ERROR_02014~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)~^~
+VALIDATION_ERROR_02015~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerInfo must be a pointer to a VkDebugMarkerMarkerInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)~^~
+VALIDATION_ERROR_02016~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)~^~
+VALIDATION_ERROR_02017~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)~^~
+VALIDATION_ERROR_02018~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)~^~
+VALIDATION_ERROR_02019~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)~^~
+VALIDATION_ERROR_02020~^~U~^~Unknown~^~vkCmdDebugMarkerBeginEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)~^~
+VALIDATION_ERROR_02021~^~U~^~Unknown~^~vkCmdDebugMarkerEndEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'There must be an outstanding vkCmdDebugMarkerBeginEXT command prior to the vkCmdDebugMarkerEndEXT on the queue that commandBuffer is submitted to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)~^~
+VALIDATION_ERROR_02022~^~U~^~Unknown~^~vkCmdDebugMarkerEndEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)~^~
+VALIDATION_ERROR_02023~^~U~^~Unknown~^~vkCmdDebugMarkerEndEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)~^~
+VALIDATION_ERROR_02024~^~U~^~Unknown~^~vkCmdDebugMarkerEndEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)~^~
+VALIDATION_ERROR_02025~^~U~^~Unknown~^~vkCmdDebugMarkerInsertEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)~^~
+VALIDATION_ERROR_02026~^~U~^~Unknown~^~vkCmdDebugMarkerInsertEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerInfo must be a pointer to a VkDebugMarkerMarkerInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)~^~
+VALIDATION_ERROR_02027~^~U~^~Unknown~^~vkCmdDebugMarkerInsertEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)~^~
+VALIDATION_ERROR_02028~^~U~^~Unknown~^~vkCmdDebugMarkerInsertEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)~^~
+VALIDATION_ERROR_02029~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02030~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pCreateInfo must be a pointer to a valid VkDebugReportCallbackCreateInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02031~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02032~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pCallback must be a pointer to a VkDebugReportCallbackEXT handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02033~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)~^~
+VALIDATION_ERROR_02034~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)~^~
+VALIDATION_ERROR_02035~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must be a valid combination of VkDebugReportFlagBitsEXT values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)~^~
+VALIDATION_ERROR_02036~^~U~^~Unknown~^~vkCreateDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)~^~
+VALIDATION_ERROR_02040~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'object may be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02041~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pLayerPrefix must be a NULL terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02042~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pMessage must be a NULL terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02043~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02044~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must be a valid combination of VkDebugReportFlagBitsEXT values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02045~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02046~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02047~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pLayerPrefix must be a pointer to a valid' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02048~^~U~^~Unknown~^~vkDebugReportMessageEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pMessage must be a pointer to a valid' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)~^~
+VALIDATION_ERROR_02049~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02050~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02051~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02052~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'callback must be a valid VkDebugReportCallbackEXT handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02053~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02054~^~U~^~Unknown~^~vkDestroyDebugReportCallbackEXT~^~For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'callback must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)~^~
+VALIDATION_ERROR_02055~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be less than or equal to the queueCount member of the VkQueueFamilyProperties structure, as returned by vkGetPhysicalDeviceQueueFamilyProperties in the pQueueFamilyProperties[queueFamilyIndex]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_02056~^~U~^~Unknown~^~vkDestroyDevice~^~For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'Each element of pQueuePriorities must be between 0.0 and 1.0 inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)~^~
+VALIDATION_ERROR_02057~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02058~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::subpass set to the index of the subpass which the given command buffer will be executed in' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02059~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with a render pass that is compatible with the current render pass - see Section 7.2, Render Pass Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02060~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, and any given element of pCommandBuffers was recorded with VkCommandBufferInheritanceInfo::framebuffer not equal to VK_NULL_HANDLE, that VkFramebuffer must match the VkFramebuffer used in the current render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02061~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is not being called within a render pass instance, any given element of pCommandBuffers must not have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02062~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If the inherited queries feature is not enabled, commandBuffer must not have any queries active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02063~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_OCCLUSION query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::occlusionQueryEnable set to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02064~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_OCCLUSION query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::queryFlags having all bits set that are set for the query' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02065~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_PIPELINE_STATISTICS query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::pipelineStatistics having all bits set that are set in the VkQueryPool the query uses' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02066~^~U~^~Unknown~^~vkCmdExecuteCommands~^~For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not begin any query types that are active in commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)~^~
+VALIDATION_ERROR_02067~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02068~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02069~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02070~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02071~^~U~^~Unknown~^~vkCmdWaitEvents~^~For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pEvents includes one or more events that will be signaled by vkSetEvent after commandBuffer has been submitted to a queue, then vkCmdWaitEvents must not be called inside a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)~^~
+VALIDATION_ERROR_02072~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must contain a subset of the bit values in the srcStageMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02073~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must contain a subset of the bit values in the dstStageMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02074~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The srcAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the srcAccessMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02075~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The dstAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the dstAccessMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02076~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dependencyFlags must be equal to the dependencyFlags member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02077~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, bufferMemoryBarrierCount must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02078~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the image member of any element of pImageMemoryBarriers must be equal to one of the elements of pAttachments that the current framebuffer was created with, that is also referred to by one of the elements of the pColorAttachments, pResolveAttachments or pDepthStencilAttachment members of the VkSubpassDescription instance that the current subpass was created with' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02079~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the oldLayout and newLayout members of any element of pImageMemoryBarriers must be equal to the layout member of an element of the pColorAttachments, pResolveAttachments or pDepthStencilAttachment members of the VkSubpassDescription instance that the current subpass was created with, that refers to the same image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02080~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the oldLayout and newLayout members of an element of pImageMemoryBarriers must be equal' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02081~^~U~^~Unknown~^~vkCmdPipelineBarrier~^~For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the srcQueueFamilyIndex and dstQueueFamilyIndex members of any element of pImageMemoryBarriers must be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)~^~
+VALIDATION_ERROR_02082~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must not declare any capability that is not supported by the API, as described by the Capabilities section of the SPIR-V Environment appendix' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_02083~^~U~^~Unknown~^~vkCreateShaderModule~^~For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pCode declares any of the capabilities that are listed as not required by the implementation, the relevant feature must be enabled, as listed in the SPIR-V Environment appendix' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)~^~
+VALIDATION_ERROR_02084~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the ClipDistance BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxClipDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02085~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the CullDistance BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxCullDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02086~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variables in its interface that are declared with the ClipDistance or CullDistance BuiltIn decoration, those variables must not have array sizes which sum to more than VkPhysicalDeviceLimits::maxCombinedClipAndCullDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02087~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the SampleMask BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxSampleMaskWords' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02088~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_VERTEX_BIT, the identified entry point must not include any input variable in its interface that is decorated with CullDistance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02089~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, and the identified entry point has an OpExecutionMode instruction that specifies a patch size with OutputVertices, the patch size must be greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02090~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must have an OpExecutionMode instruction that specifies a maximum output vertex count that is greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxGeometryOutputVertices' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02091~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must have an OpExecutionMode instruction that specifies an invocation count that is greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxGeometryShaderInvocations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02092~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to Layer for any primitive, it must write the same value to Layer for all vertices of a given primitive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02093~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to ViewportIndex for any primitive, it must write the same value to ViewportIndex for all vertices of a given primitive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02094~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_FRAGMENT_BIT, the identified entry point must not include any output variables in its interface decorated with CullDistance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02095~^~U~^~Unknown~^~vkCreateComputePipelines~^~For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_FRAGMENT_BIT, and the identified entry point writes to FragDepth in any execution path, it must write to FragDepth in all execution paths' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)~^~
+VALIDATION_ERROR_02096~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both stages contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must both specify the same subdivision mode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02097~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the output patch size in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02098~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both contain an OpExecutionMode instruction that specifies the out patch size in the pipeline, they must both specify the same patch size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02099~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the topology member of pInputAssembly must be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02100~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the topology member of pInputAssembly is VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pStages must include tessellation shader stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02101~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and does not include any tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology specified in pInputAssembly' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02102~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology that is output by the tessellation stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02103~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a fragment shader stage and a geometry shader stage, and the fragment shader code reads from an input variable that is decorated with PrimitiveID, then the geometry shader code must write to a matching output variable, decorated with PrimitiveID, in all execution paths' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02104~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a fragment shader stage, its shader code must not read from any input attachment that is defined as VK_ATTACHMENT_UNUSED in subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02105~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The shader code for the entry points identified by pStages, and the rest of the state identified by this structure must adhere to the pipeline linking rules described in the Shader Interfaces chapter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02106~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses a depth/stencil attachment in renderpass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the VkAttachmentReference defined by subpass, and pDepthStencilState is not NULL, the depthWriteEnable member of pDepthStencilState must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02107~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses a depth/stencil attachment in renderpass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the VkAttachmentReference defined by subpass, and pDepthStencilState is not NULL, the failOp, passOp and depthFailOp members of each of the front and back members of pDepthStencilState must be VK_STENCIL_OP_KEEP' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02108~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pColorBlendState is not NULL, the blendEnable member of each element of the pAttachment member of pColorBlendState must be VK_FALSE if the format of the attachment referred to in subpass of renderPass does not support color blend operations, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT flag in VkFormatProperties::linearTilingFeatures or VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02109~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pColorBlendState is not NULL, The attachmentCount member of pColorBlendState must be equal to the colorAttachmentCount used to create subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02110~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_VIEWPORT, the pViewports member of pViewportState must be a pointer to an array of pViewportState::viewportCount VkViewport structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02111~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_SCISSOR, the pScissors member of pViewportState must be a pointer to an array of pViewportState::scissorCount VkRect2D structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02112~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the wide lines feature is not enabled, and no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_LINE_WIDTH, the lineWidth member of pRasterizationState must be 1.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02113~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pViewportState must be a pointer to a valid VkPipelineViewportStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02114~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pMultisampleState must be a pointer to a valid VkPipelineMultisampleStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02115~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, and subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid VkPipelineDepthStencilStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02116~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, and subpass uses color attachments, pColorBlendState must be a pointer to a valid VkPipelineColorBlendStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02117~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the depth bias clamping feature is not enabled, no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_DEPTH_BIAS, and the depthBiasEnable member of pDepthStencil is VK_TRUE, the depthBiasClamp member of pDepthStencil must be 0.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02118~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_DEPTH_BOUNDS, and the depthBoundsTestEnable member of pDepthStencil is VK_TRUE, the minDepthBounds and maxDepthBounds members of pDepthStencil must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02119~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'layout must be consistent with all shaders specified in pStages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02120~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of pMultisampleState must be the same as the sample count for those subpass attachments' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02121~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass does not use any color and/or depth/stencil attachments, then the rasterizationSamples member of pMultisampleState must follow the rules for a zero-attachment subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02122~^~U~^~Unknown~^~vkCreateGraphicsPipelines~^~For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'subpass must be a valid subpass within renderpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)~^~
+VALIDATION_ERROR_02123~^~U~^~Unknown~^~vkCreatePipelineCache~^~For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, pInitialData must have been retrieved from a previous call to vkGetPipelineCacheData' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)~^~
+VALIDATION_ERROR_02124~^~U~^~Unknown~^~vkCreateBufferView~^~For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If buffer was created with usage containing VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, format must be supported for storage texel buffers, as specified by the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)~^~
+VALIDATION_ERROR_02125~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags does not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension2D, or VkImageFormatProperties::maxExtent.width/height (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02126~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be less than or equal to VkPhysicalDeviceLimits::maxImageDimensionCube, or VkImageFormatProperties::maxExtent.width/height (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02127~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be equal and arrayLayers must be greater than or equal to 6' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02128~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_3D, extent.width, extent.height and extent.depth must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension3D, or VkImageFormatProperties::maxExtent.width/height/depth (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02129~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02130~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D, extent.depth must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02131~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevels must be less than or equal to log2(max(extent.width, extent.height, extent.depth)) + 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02132~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If any of extent.width, extent.height, or extent.depth are greater than the equivalently named members of VkPhysicalDeviceLimits::maxImageDimension3D, mipLevels must be less than or equal to VkImageFormatProperties::maxMipLevels (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02133~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayers must be less than or equal to VkImageFormatProperties::maxArrayLayers (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02134~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If samples is not VK_SAMPLE_COUNT_1_BIT, imageType must be VK_IMAGE_TYPE_2D, flags must not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, tiling must be VK_IMAGE_TILING_OPTIMAL, and mipLevels must be equal to 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02135~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, then bits other than VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT must not be set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02136~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.width must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferWidth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02137~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.height must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferHeight' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02138~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'samples must be a bit value that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02139~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the ETC2 texture compression feature is not enabled, format must not be VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or VK_FORMAT_EAC_R11G11_SNORM_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02140~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the ASTC LDR texture compression feature is not enabled, format must not be VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or VK_FORMAT_ASTC_12x12_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02141~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the BC texture compression feature is not enabled, format must not be VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, or VK_FORMAT_BC7_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02142~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the multisampled storage images feature is not enabled, and usage contains VK_IMAGE_USAGE_STORAGE_BIT, samples must be VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02143~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse bindings feature is not enabled, flags must not contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02144~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for 2D images feature is not enabled, and imageType is VK_IMAGE_TYPE_2D, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02145~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for 3D images feature is not enabled, and imageType is VK_IMAGE_TYPE_3D, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02146~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 2 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_2_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02147~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 4 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_4_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02148~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 8 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_8_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02149~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 16 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_16_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02150~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, format must be a format that has at least one supported feature bit present in the value of VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02151~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_SAMPLED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02152~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_STORAGE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02153~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02154~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02155~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, format must be a format that has at least one supported feature bit present in the value of VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02156~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_SAMPLED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02157~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_STORAGE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02158~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02159~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02160~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02161~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_SAMPLED_BIT, format must be supported for sampled images, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02162~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_STORAGE_BIT, format must be supported for storage images, as specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02163~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02164~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format must be supported for depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02165~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL, format must be format that has at least one supported feature bit present in the value of VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02166~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_SAMPLED_BIT, format must be supported for sampled images, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02167~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_STORAGE_BIT, format must be supported for storage images, as specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02168~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02169~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format must be supported for depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02170~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subresourceRange must be a valid image subresource range for image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02171~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, format must be compatible with the format used to create image, as defined in Format Compatibility Classes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02172~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, format must be identical to the format used to create image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02173~^~U~^~Unknown~^~vkCreateImageView~^~For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subResourceRange and viewType must be compatible with the image, as described in the compatibility table' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)~^~
+VALIDATION_ERROR_02174~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_02175~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'The size member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_02176~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::buffer equal to buffer and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_02177~^~U~^~Unknown~^~vkBindBufferMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was not created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)~^~
+VALIDATION_ERROR_02178~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_02179~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'The size member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_02180~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If image was created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::image equal to image and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_02181~^~U~^~Unknown~^~vkBindImageMemory~^~For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If image was not created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)~^~
+VALIDATION_ERROR_02182~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02183~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02184~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02185~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must use a format that supports VK_FORMAT_FEATURE_BLIT_DST_BIT, which is indicated by VkFormatProperties::linearTilingFeatures (for linear tiled images) or VkFormatProperties::optimalTilingFeatures (for optimally tiled images) - as returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02186~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02187~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02188~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02189~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The sample count of srcImage and dstImage must both be equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02190~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with a signed integer VkFormat, the other must also have been created with a signed integer VkFormat' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02191~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with an unsigned integer VkFormat, the other must also have been created with an unsigned integer VkFormat' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02192~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with a depth/stencil format, the other must have exactly the same format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02193~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If srcImage was created with a depth/stencil format, filter must be VK_FILTER_NEAREST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02194~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02195~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02196~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_LINEAR, srcImage must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02197~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_CUBIC_IMG, srcImage must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02198~^~U~^~Unknown~^~vkCmdBlitImage~^~For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_CUBIC_IMG, srcImage must have a VkImageType of VK_IMAGE_TYPE_3D' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)~^~
+VALIDATION_ERROR_02199~^~U~^~Unknown~^~vkCmdResolveImage~^~For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If dstImage was created with tiling equal to VK_IMAGE_TILING_OPTIMAL, dstImage must have been created with a format that supports being a color attachment, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)~^~
+VALIDATION_ERROR_02200~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02201~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02202~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02203~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02204~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02205~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02206~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02207~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02208~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02209~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02210~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02211~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02212~^~U~^~Unknown~^~vkCmdDraw~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)~^~
+VALIDATION_ERROR_02213~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02214~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02215~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02216~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02217~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states '(indexSize * (firstIndex + indexCount) + offset) must be less than or equal to the size of the currently bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexType, and offset are specified via vkCmdBindIndexBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02218~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02219~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02220~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02221~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02222~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02223~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02224~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02225~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02226~^~U~^~Unknown~^~vkCmdDrawIndexed~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)~^~
+VALIDATION_ERROR_02227~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02228~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02229~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02230~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02231~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02232~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02233~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02234~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02235~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is equal to 1, (offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02236~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02237~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02238~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02239~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02240~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02241~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02242~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02243~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02244~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02245~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02246~^~U~^~Unknown~^~vkCmdDrawIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)~^~
+VALIDATION_ERROR_02247~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02248~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02249~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02250~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02251~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02252~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02253~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02254~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02255~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02256~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the count stored in countBuffer is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02257~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The count stored in countBuffer must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02258~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02259~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02260~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02261~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02262~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02263~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02264~^~U~^~Unknown~^~vkCmdDrawIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)~^~
+VALIDATION_ERROR_02265~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02266~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02267~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02268~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02269~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02270~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02271~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02272~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02273~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02274~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02275~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02276~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02277~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02278~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02279~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02280~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02281~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02282~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02283~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02284~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)~^~
+VALIDATION_ERROR_02285~^~U~^~Unknown~^~vkCmdDrawIndexedIndirect~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)~^~
+VALIDATION_ERROR_02286~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02287~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02288~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02289~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02290~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02291~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02292~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02293~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02294~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02295~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If count stored in countBuffer is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02296~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02297~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02298~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02299~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02300~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02301~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02302~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02303~^~U~^~Unknown~^~vkCmdDrawIndexedIndirectCountAMD~^~For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)~^~
+VALIDATION_ERROR_02304~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'A valid compute pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02305~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with the one used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02306~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02307~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02308~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02309~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02310~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02311~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02312~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02313~^~U~^~Unknown~^~vkCmdDispatch~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)~^~
+VALIDATION_ERROR_02314~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'A valid compute pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02315~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'buffer must have been created with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02316~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02317~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The sum of offset and the size of VkDispatchIndirectCommand must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02318~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with the one used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02319~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02320~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02321~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02322~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02323~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02324~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02325~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02326~^~U~^~Unknown~^~vkCmdDispatchIndirect~^~For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)~^~
+VALIDATION_ERROR_02327~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If the planeReorderPossible member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display corresponding to displayMode is VK_TRUE then planeStackIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR; otherwise planeStackIndex must equal the currentStackIndex member of VkDisplayPlanePropertiesKHR returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR for the display plane corresponding to displayMode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_02328~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If alphaMode is VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR then globalAlpha must be between 0 and 1, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_02329~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'alphaMode must be 0 or one of the bits present in the supportedAlpha member of VkDisplayPlaneCapabilitiesKHR returned by vkGetDisplayPlaneCapabilitiesKHR for the display plane corresponding to displayMode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_02330~^~U~^~Unknown~^~vkCreateDisplayPlaneSurfaceKHR~^~For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'The width and height members of imageExtent must be less than the maxImageDimensions2D member of VkPhysicalDeviceLimits' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)~^~
+VALIDATION_ERROR_02331~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'minImageCount must be greater than or equal to the value returned in the minImageCount member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02332~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'minImageCount must be less than or equal to the value returned in the maxImageCount member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface if the returned maxImageCount is not zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02333~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageFormat and imageColorSpace must match the format and colorSpace members, respectively, of one of the VkSurfaceFormatKHR structures returned by vkGetPhysicalDeviceSurfaceFormatsKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02334~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02335~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageArrayLayers must be greater than 0 and less than or equal to the maxImageArrayLayers member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02336~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must be a subset of the supported usage flags present in the supportedUsageFlags member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02337~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If imageSharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02338~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If imageSharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02339~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'preTransform must be one of the bits present in the supportedTransforms member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02340~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'compositeAlpha must be one of the bits present in the supportedCompositeAlpha member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02341~^~U~^~Unknown~^~vkCreateSwapchainKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'presentMode must be one of the VkPresentModeKHR values returned by vkGetPhysicalDeviceSurfacePresentModesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)~^~
+VALIDATION_ERROR_02342~^~U~^~Unknown~^~vkQueuePresentKHR~^~For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If more than one member of pSwapchains was created from a display surface, all display surfaces referenced that refer to the same display must use the same display mode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)~^~
+VALIDATION_ERROR_02343~^~U~^~Unknown~^~vkCmdDebugMarkerEndEXT~^~For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'If the matching vkCmdDebugMarkerBeginEXT command was in a secondary command buffer, the vkCmdDebugMarkerEndEXT must be in the same commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)~^~
+VALIDATION_ERROR_02344~^~U~^~Unknown~^~vkCreateImage~^~For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_3D, arrayLayers must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)~^~
+VALIDATION_ERROR_02345~^~Y~^~DuplicateDescriptorBinding~^~vkCreateDescriptorSetLayout~^~For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'The VkDescriptorSetLayoutBinding::binding members of the elements of the pBindings array must each have different values.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)~^~
+
diff --git a/layers/vk_validation_error_messages.h b/layers/vk_validation_error_messages.h
new file mode 100644
index 0000000..9d786cf
--- /dev/null
+++ b/layers/vk_validation_error_messages.h
@@ -0,0 +1,4605 @@
+/* THIS FILE IS GENERATED.  DO NOT EDIT. */
+
+/*
+ * Vulkan
+ *
+ * Copyright (c) 2016 Google Inc.
+ * Copyright (c) 2016 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>
+ */
+
+#pragma once
+#include <unordered_map>
+
+// enum values for unique validation error codes
+//  Corresponding validation error message for each enum is given in the mapping table below
+//  When a given error occurs, these enum values should be passed to the as the messageCode
+//  parameter to the PFN_vkDebugReportCallbackEXT function
+enum UNIQUE_VALIDATION_ERROR_CODE {
+    VALIDATION_ERROR_00000 = 0,
+    VALIDATION_ERROR_00001 = 1,
+    VALIDATION_ERROR_00002 = 2,
+    VALIDATION_ERROR_00003 = 3,
+    VALIDATION_ERROR_00004 = 4,
+    VALIDATION_ERROR_00005 = 5,
+    VALIDATION_ERROR_00006 = 6,
+    VALIDATION_ERROR_00007 = 7,
+    VALIDATION_ERROR_00008 = 8,
+    VALIDATION_ERROR_00009 = 9,
+    VALIDATION_ERROR_00010 = 10,
+    VALIDATION_ERROR_00011 = 11,
+    VALIDATION_ERROR_00012 = 12,
+    VALIDATION_ERROR_00013 = 13,
+    VALIDATION_ERROR_00014 = 14,
+    VALIDATION_ERROR_00015 = 15,
+    VALIDATION_ERROR_00016 = 16,
+    VALIDATION_ERROR_00017 = 17,
+    VALIDATION_ERROR_00018 = 18,
+    VALIDATION_ERROR_00019 = 19,
+    VALIDATION_ERROR_00020 = 20,
+    VALIDATION_ERROR_00021 = 21,
+    VALIDATION_ERROR_00022 = 22,
+    VALIDATION_ERROR_00023 = 23,
+    VALIDATION_ERROR_00024 = 24,
+    VALIDATION_ERROR_00025 = 25,
+    VALIDATION_ERROR_00026 = 26,
+    VALIDATION_ERROR_00027 = 27,
+    VALIDATION_ERROR_00028 = 28,
+    VALIDATION_ERROR_00029 = 29,
+    VALIDATION_ERROR_00030 = 30,
+    VALIDATION_ERROR_00031 = 31,
+    VALIDATION_ERROR_00032 = 32,
+    VALIDATION_ERROR_00033 = 33,
+    VALIDATION_ERROR_00034 = 34,
+    VALIDATION_ERROR_00035 = 35,
+    VALIDATION_ERROR_00036 = 36,
+    VALIDATION_ERROR_00037 = 37,
+    VALIDATION_ERROR_00038 = 38,
+    VALIDATION_ERROR_00039 = 39,
+    VALIDATION_ERROR_00040 = 40,
+    VALIDATION_ERROR_00041 = 41,
+    VALIDATION_ERROR_00042 = 42,
+    VALIDATION_ERROR_00043 = 43,
+    VALIDATION_ERROR_00049 = 49,
+    VALIDATION_ERROR_00050 = 50,
+    VALIDATION_ERROR_00051 = 51,
+    VALIDATION_ERROR_00052 = 52,
+    VALIDATION_ERROR_00053 = 53,
+    VALIDATION_ERROR_00054 = 54,
+    VALIDATION_ERROR_00055 = 55,
+    VALIDATION_ERROR_00056 = 56,
+    VALIDATION_ERROR_00057 = 57,
+    VALIDATION_ERROR_00058 = 58,
+    VALIDATION_ERROR_00059 = 59,
+    VALIDATION_ERROR_00060 = 60,
+    VALIDATION_ERROR_00061 = 61,
+    VALIDATION_ERROR_00062 = 62,
+    VALIDATION_ERROR_00063 = 63,
+    VALIDATION_ERROR_00064 = 64,
+    VALIDATION_ERROR_00065 = 65,
+    VALIDATION_ERROR_00066 = 66,
+    VALIDATION_ERROR_00067 = 67,
+    VALIDATION_ERROR_00068 = 68,
+    VALIDATION_ERROR_00069 = 69,
+    VALIDATION_ERROR_00070 = 70,
+    VALIDATION_ERROR_00071 = 71,
+    VALIDATION_ERROR_00072 = 72,
+    VALIDATION_ERROR_00073 = 73,
+    VALIDATION_ERROR_00074 = 74,
+    VALIDATION_ERROR_00075 = 75,
+    VALIDATION_ERROR_00076 = 76,
+    VALIDATION_ERROR_00077 = 77,
+    VALIDATION_ERROR_00078 = 78,
+    VALIDATION_ERROR_00079 = 79,
+    VALIDATION_ERROR_00080 = 80,
+    VALIDATION_ERROR_00081 = 81,
+    VALIDATION_ERROR_00082 = 82,
+    VALIDATION_ERROR_00083 = 83,
+    VALIDATION_ERROR_00084 = 84,
+    VALIDATION_ERROR_00085 = 85,
+    VALIDATION_ERROR_00086 = 86,
+    VALIDATION_ERROR_00087 = 87,
+    VALIDATION_ERROR_00088 = 88,
+    VALIDATION_ERROR_00089 = 89,
+    VALIDATION_ERROR_00090 = 90,
+    VALIDATION_ERROR_00091 = 91,
+    VALIDATION_ERROR_00092 = 92,
+    VALIDATION_ERROR_00093 = 93,
+    VALIDATION_ERROR_00094 = 94,
+    VALIDATION_ERROR_00095 = 95,
+    VALIDATION_ERROR_00096 = 96,
+    VALIDATION_ERROR_00097 = 97,
+    VALIDATION_ERROR_00098 = 98,
+    VALIDATION_ERROR_00099 = 99,
+    VALIDATION_ERROR_00100 = 100,
+    VALIDATION_ERROR_00101 = 101,
+    VALIDATION_ERROR_00102 = 102,
+    VALIDATION_ERROR_00103 = 103,
+    VALIDATION_ERROR_00104 = 104,
+    VALIDATION_ERROR_00105 = 105,
+    VALIDATION_ERROR_00106 = 106,
+    VALIDATION_ERROR_00107 = 107,
+    VALIDATION_ERROR_00108 = 108,
+    VALIDATION_ERROR_00109 = 109,
+    VALIDATION_ERROR_00110 = 110,
+    VALIDATION_ERROR_00111 = 111,
+    VALIDATION_ERROR_00112 = 112,
+    VALIDATION_ERROR_00113 = 113,
+    VALIDATION_ERROR_00114 = 114,
+    VALIDATION_ERROR_00115 = 115,
+    VALIDATION_ERROR_00116 = 116,
+    VALIDATION_ERROR_00117 = 117,
+    VALIDATION_ERROR_00118 = 118,
+    VALIDATION_ERROR_00119 = 119,
+    VALIDATION_ERROR_00120 = 120,
+    VALIDATION_ERROR_00121 = 121,
+    VALIDATION_ERROR_00122 = 122,
+    VALIDATION_ERROR_00123 = 123,
+    VALIDATION_ERROR_00124 = 124,
+    VALIDATION_ERROR_00125 = 125,
+    VALIDATION_ERROR_00126 = 126,
+    VALIDATION_ERROR_00127 = 127,
+    VALIDATION_ERROR_00128 = 128,
+    VALIDATION_ERROR_00129 = 129,
+    VALIDATION_ERROR_00130 = 130,
+    VALIDATION_ERROR_00131 = 131,
+    VALIDATION_ERROR_00132 = 132,
+    VALIDATION_ERROR_00133 = 133,
+    VALIDATION_ERROR_00134 = 134,
+    VALIDATION_ERROR_00135 = 135,
+    VALIDATION_ERROR_00136 = 136,
+    VALIDATION_ERROR_00137 = 137,
+    VALIDATION_ERROR_00138 = 138,
+    VALIDATION_ERROR_00139 = 139,
+    VALIDATION_ERROR_00140 = 140,
+    VALIDATION_ERROR_00141 = 141,
+    VALIDATION_ERROR_00142 = 142,
+    VALIDATION_ERROR_00143 = 143,
+    VALIDATION_ERROR_00144 = 144,
+    VALIDATION_ERROR_00145 = 145,
+    VALIDATION_ERROR_00146 = 146,
+    VALIDATION_ERROR_00147 = 147,
+    VALIDATION_ERROR_00148 = 148,
+    VALIDATION_ERROR_00149 = 149,
+    VALIDATION_ERROR_00150 = 150,
+    VALIDATION_ERROR_00151 = 151,
+    VALIDATION_ERROR_00152 = 152,
+    VALIDATION_ERROR_00153 = 153,
+    VALIDATION_ERROR_00154 = 154,
+    VALIDATION_ERROR_00155 = 155,
+    VALIDATION_ERROR_00156 = 156,
+    VALIDATION_ERROR_00157 = 157,
+    VALIDATION_ERROR_00158 = 158,
+    VALIDATION_ERROR_00159 = 159,
+    VALIDATION_ERROR_00160 = 160,
+    VALIDATION_ERROR_00161 = 161,
+    VALIDATION_ERROR_00162 = 162,
+    VALIDATION_ERROR_00163 = 163,
+    VALIDATION_ERROR_00164 = 164,
+    VALIDATION_ERROR_00165 = 165,
+    VALIDATION_ERROR_00166 = 166,
+    VALIDATION_ERROR_00167 = 167,
+    VALIDATION_ERROR_00168 = 168,
+    VALIDATION_ERROR_00169 = 169,
+    VALIDATION_ERROR_00170 = 170,
+    VALIDATION_ERROR_00171 = 171,
+    VALIDATION_ERROR_00172 = 172,
+    VALIDATION_ERROR_00173 = 173,
+    VALIDATION_ERROR_00174 = 174,
+    VALIDATION_ERROR_00175 = 175,
+    VALIDATION_ERROR_00176 = 176,
+    VALIDATION_ERROR_00177 = 177,
+    VALIDATION_ERROR_00178 = 178,
+    VALIDATION_ERROR_00179 = 179,
+    VALIDATION_ERROR_00180 = 180,
+    VALIDATION_ERROR_00181 = 181,
+    VALIDATION_ERROR_00182 = 182,
+    VALIDATION_ERROR_00183 = 183,
+    VALIDATION_ERROR_00184 = 184,
+    VALIDATION_ERROR_00185 = 185,
+    VALIDATION_ERROR_00186 = 186,
+    VALIDATION_ERROR_00187 = 187,
+    VALIDATION_ERROR_00188 = 188,
+    VALIDATION_ERROR_00189 = 189,
+    VALIDATION_ERROR_00190 = 190,
+    VALIDATION_ERROR_00191 = 191,
+    VALIDATION_ERROR_00192 = 192,
+    VALIDATION_ERROR_00193 = 193,
+    VALIDATION_ERROR_00194 = 194,
+    VALIDATION_ERROR_00195 = 195,
+    VALIDATION_ERROR_00196 = 196,
+    VALIDATION_ERROR_00197 = 197,
+    VALIDATION_ERROR_00198 = 198,
+    VALIDATION_ERROR_00199 = 199,
+    VALIDATION_ERROR_00200 = 200,
+    VALIDATION_ERROR_00201 = 201,
+    VALIDATION_ERROR_00202 = 202,
+    VALIDATION_ERROR_00203 = 203,
+    VALIDATION_ERROR_00204 = 204,
+    VALIDATION_ERROR_00205 = 205,
+    VALIDATION_ERROR_00206 = 206,
+    VALIDATION_ERROR_00207 = 207,
+    VALIDATION_ERROR_00208 = 208,
+    VALIDATION_ERROR_00209 = 209,
+    VALIDATION_ERROR_00210 = 210,
+    VALIDATION_ERROR_00211 = 211,
+    VALIDATION_ERROR_00212 = 212,
+    VALIDATION_ERROR_00213 = 213,
+    VALIDATION_ERROR_00214 = 214,
+    VALIDATION_ERROR_00215 = 215,
+    VALIDATION_ERROR_00216 = 216,
+    VALIDATION_ERROR_00217 = 217,
+    VALIDATION_ERROR_00218 = 218,
+    VALIDATION_ERROR_00219 = 219,
+    VALIDATION_ERROR_00220 = 220,
+    VALIDATION_ERROR_00221 = 221,
+    VALIDATION_ERROR_00222 = 222,
+    VALIDATION_ERROR_00223 = 223,
+    VALIDATION_ERROR_00224 = 224,
+    VALIDATION_ERROR_00225 = 225,
+    VALIDATION_ERROR_00226 = 226,
+    VALIDATION_ERROR_00227 = 227,
+    VALIDATION_ERROR_00228 = 228,
+    VALIDATION_ERROR_00229 = 229,
+    VALIDATION_ERROR_00230 = 230,
+    VALIDATION_ERROR_00231 = 231,
+    VALIDATION_ERROR_00232 = 232,
+    VALIDATION_ERROR_00233 = 233,
+    VALIDATION_ERROR_00234 = 234,
+    VALIDATION_ERROR_00235 = 235,
+    VALIDATION_ERROR_00236 = 236,
+    VALIDATION_ERROR_00237 = 237,
+    VALIDATION_ERROR_00238 = 238,
+    VALIDATION_ERROR_00239 = 239,
+    VALIDATION_ERROR_00240 = 240,
+    VALIDATION_ERROR_00241 = 241,
+    VALIDATION_ERROR_00242 = 242,
+    VALIDATION_ERROR_00243 = 243,
+    VALIDATION_ERROR_00244 = 244,
+    VALIDATION_ERROR_00245 = 245,
+    VALIDATION_ERROR_00246 = 246,
+    VALIDATION_ERROR_00247 = 247,
+    VALIDATION_ERROR_00248 = 248,
+    VALIDATION_ERROR_00249 = 249,
+    VALIDATION_ERROR_00250 = 250,
+    VALIDATION_ERROR_00251 = 251,
+    VALIDATION_ERROR_00252 = 252,
+    VALIDATION_ERROR_00253 = 253,
+    VALIDATION_ERROR_00254 = 254,
+    VALIDATION_ERROR_00255 = 255,
+    VALIDATION_ERROR_00256 = 256,
+    VALIDATION_ERROR_00257 = 257,
+    VALIDATION_ERROR_00258 = 258,
+    VALIDATION_ERROR_00259 = 259,
+    VALIDATION_ERROR_00260 = 260,
+    VALIDATION_ERROR_00261 = 261,
+    VALIDATION_ERROR_00262 = 262,
+    VALIDATION_ERROR_00263 = 263,
+    VALIDATION_ERROR_00264 = 264,
+    VALIDATION_ERROR_00265 = 265,
+    VALIDATION_ERROR_00266 = 266,
+    VALIDATION_ERROR_00267 = 267,
+    VALIDATION_ERROR_00268 = 268,
+    VALIDATION_ERROR_00269 = 269,
+    VALIDATION_ERROR_00270 = 270,
+    VALIDATION_ERROR_00271 = 271,
+    VALIDATION_ERROR_00272 = 272,
+    VALIDATION_ERROR_00273 = 273,
+    VALIDATION_ERROR_00274 = 274,
+    VALIDATION_ERROR_00275 = 275,
+    VALIDATION_ERROR_00276 = 276,
+    VALIDATION_ERROR_00277 = 277,
+    VALIDATION_ERROR_00278 = 278,
+    VALIDATION_ERROR_00279 = 279,
+    VALIDATION_ERROR_00280 = 280,
+    VALIDATION_ERROR_00281 = 281,
+    VALIDATION_ERROR_00282 = 282,
+    VALIDATION_ERROR_00283 = 283,
+    VALIDATION_ERROR_00284 = 284,
+    VALIDATION_ERROR_00285 = 285,
+    VALIDATION_ERROR_00286 = 286,
+    VALIDATION_ERROR_00287 = 287,
+    VALIDATION_ERROR_00288 = 288,
+    VALIDATION_ERROR_00289 = 289,
+    VALIDATION_ERROR_00290 = 290,
+    VALIDATION_ERROR_00291 = 291,
+    VALIDATION_ERROR_00292 = 292,
+    VALIDATION_ERROR_00293 = 293,
+    VALIDATION_ERROR_00294 = 294,
+    VALIDATION_ERROR_00295 = 295,
+    VALIDATION_ERROR_00296 = 296,
+    VALIDATION_ERROR_00297 = 297,
+    VALIDATION_ERROR_00298 = 298,
+    VALIDATION_ERROR_00299 = 299,
+    VALIDATION_ERROR_00300 = 300,
+    VALIDATION_ERROR_00301 = 301,
+    VALIDATION_ERROR_00302 = 302,
+    VALIDATION_ERROR_00303 = 303,
+    VALIDATION_ERROR_00304 = 304,
+    VALIDATION_ERROR_00305 = 305,
+    VALIDATION_ERROR_00306 = 306,
+    VALIDATION_ERROR_00307 = 307,
+    VALIDATION_ERROR_00308 = 308,
+    VALIDATION_ERROR_00309 = 309,
+    VALIDATION_ERROR_00310 = 310,
+    VALIDATION_ERROR_00311 = 311,
+    VALIDATION_ERROR_00312 = 312,
+    VALIDATION_ERROR_00313 = 313,
+    VALIDATION_ERROR_00314 = 314,
+    VALIDATION_ERROR_00315 = 315,
+    VALIDATION_ERROR_00316 = 316,
+    VALIDATION_ERROR_00317 = 317,
+    VALIDATION_ERROR_00318 = 318,
+    VALIDATION_ERROR_00319 = 319,
+    VALIDATION_ERROR_00320 = 320,
+    VALIDATION_ERROR_00321 = 321,
+    VALIDATION_ERROR_00322 = 322,
+    VALIDATION_ERROR_00323 = 323,
+    VALIDATION_ERROR_00324 = 324,
+    VALIDATION_ERROR_00325 = 325,
+    VALIDATION_ERROR_00326 = 326,
+    VALIDATION_ERROR_00327 = 327,
+    VALIDATION_ERROR_00328 = 328,
+    VALIDATION_ERROR_00329 = 329,
+    VALIDATION_ERROR_00330 = 330,
+    VALIDATION_ERROR_00331 = 331,
+    VALIDATION_ERROR_00332 = 332,
+    VALIDATION_ERROR_00333 = 333,
+    VALIDATION_ERROR_00334 = 334,
+    VALIDATION_ERROR_00335 = 335,
+    VALIDATION_ERROR_00336 = 336,
+    VALIDATION_ERROR_00337 = 337,
+    VALIDATION_ERROR_00338 = 338,
+    VALIDATION_ERROR_00339 = 339,
+    VALIDATION_ERROR_00340 = 340,
+    VALIDATION_ERROR_00341 = 341,
+    VALIDATION_ERROR_00342 = 342,
+    VALIDATION_ERROR_00343 = 343,
+    VALIDATION_ERROR_00347 = 347,
+    VALIDATION_ERROR_00348 = 348,
+    VALIDATION_ERROR_00349 = 349,
+    VALIDATION_ERROR_00350 = 350,
+    VALIDATION_ERROR_00351 = 351,
+    VALIDATION_ERROR_00352 = 352,
+    VALIDATION_ERROR_00353 = 353,
+    VALIDATION_ERROR_00354 = 354,
+    VALIDATION_ERROR_00355 = 355,
+    VALIDATION_ERROR_00356 = 356,
+    VALIDATION_ERROR_00357 = 357,
+    VALIDATION_ERROR_00358 = 358,
+    VALIDATION_ERROR_00359 = 359,
+    VALIDATION_ERROR_00360 = 360,
+    VALIDATION_ERROR_00361 = 361,
+    VALIDATION_ERROR_00362 = 362,
+    VALIDATION_ERROR_00363 = 363,
+    VALIDATION_ERROR_00364 = 364,
+    VALIDATION_ERROR_00365 = 365,
+    VALIDATION_ERROR_00366 = 366,
+    VALIDATION_ERROR_00367 = 367,
+    VALIDATION_ERROR_00368 = 368,
+    VALIDATION_ERROR_00369 = 369,
+    VALIDATION_ERROR_00370 = 370,
+    VALIDATION_ERROR_00371 = 371,
+    VALIDATION_ERROR_00372 = 372,
+    VALIDATION_ERROR_00373 = 373,
+    VALIDATION_ERROR_00374 = 374,
+    VALIDATION_ERROR_00375 = 375,
+    VALIDATION_ERROR_00376 = 376,
+    VALIDATION_ERROR_00377 = 377,
+    VALIDATION_ERROR_00378 = 378,
+    VALIDATION_ERROR_00379 = 379,
+    VALIDATION_ERROR_00380 = 380,
+    VALIDATION_ERROR_00381 = 381,
+    VALIDATION_ERROR_00382 = 382,
+    VALIDATION_ERROR_00393 = 393,
+    VALIDATION_ERROR_00394 = 394,
+    VALIDATION_ERROR_00395 = 395,
+    VALIDATION_ERROR_00396 = 396,
+    VALIDATION_ERROR_00397 = 397,
+    VALIDATION_ERROR_00398 = 398,
+    VALIDATION_ERROR_00399 = 399,
+    VALIDATION_ERROR_00400 = 400,
+    VALIDATION_ERROR_00401 = 401,
+    VALIDATION_ERROR_00402 = 402,
+    VALIDATION_ERROR_00403 = 403,
+    VALIDATION_ERROR_00404 = 404,
+    VALIDATION_ERROR_00405 = 405,
+    VALIDATION_ERROR_00406 = 406,
+    VALIDATION_ERROR_00407 = 407,
+    VALIDATION_ERROR_00408 = 408,
+    VALIDATION_ERROR_00409 = 409,
+    VALIDATION_ERROR_00410 = 410,
+    VALIDATION_ERROR_00411 = 411,
+    VALIDATION_ERROR_00412 = 412,
+    VALIDATION_ERROR_00413 = 413,
+    VALIDATION_ERROR_00414 = 414,
+    VALIDATION_ERROR_00415 = 415,
+    VALIDATION_ERROR_00416 = 416,
+    VALIDATION_ERROR_00417 = 417,
+    VALIDATION_ERROR_00418 = 418,
+    VALIDATION_ERROR_00419 = 419,
+    VALIDATION_ERROR_00420 = 420,
+    VALIDATION_ERROR_00421 = 421,
+    VALIDATION_ERROR_00422 = 422,
+    VALIDATION_ERROR_00423 = 423,
+    VALIDATION_ERROR_00424 = 424,
+    VALIDATION_ERROR_00425 = 425,
+    VALIDATION_ERROR_00426 = 426,
+    VALIDATION_ERROR_00427 = 427,
+    VALIDATION_ERROR_00428 = 428,
+    VALIDATION_ERROR_00429 = 429,
+    VALIDATION_ERROR_00430 = 430,
+    VALIDATION_ERROR_00431 = 431,
+    VALIDATION_ERROR_00432 = 432,
+    VALIDATION_ERROR_00433 = 433,
+    VALIDATION_ERROR_00434 = 434,
+    VALIDATION_ERROR_00435 = 435,
+    VALIDATION_ERROR_00436 = 436,
+    VALIDATION_ERROR_00437 = 437,
+    VALIDATION_ERROR_00438 = 438,
+    VALIDATION_ERROR_00439 = 439,
+    VALIDATION_ERROR_00440 = 440,
+    VALIDATION_ERROR_00441 = 441,
+    VALIDATION_ERROR_00442 = 442,
+    VALIDATION_ERROR_00443 = 443,
+    VALIDATION_ERROR_00444 = 444,
+    VALIDATION_ERROR_00445 = 445,
+    VALIDATION_ERROR_00446 = 446,
+    VALIDATION_ERROR_00447 = 447,
+    VALIDATION_ERROR_00448 = 448,
+    VALIDATION_ERROR_00449 = 449,
+    VALIDATION_ERROR_00450 = 450,
+    VALIDATION_ERROR_00451 = 451,
+    VALIDATION_ERROR_00452 = 452,
+    VALIDATION_ERROR_00453 = 453,
+    VALIDATION_ERROR_00454 = 454,
+    VALIDATION_ERROR_00455 = 455,
+    VALIDATION_ERROR_00456 = 456,
+    VALIDATION_ERROR_00457 = 457,
+    VALIDATION_ERROR_00458 = 458,
+    VALIDATION_ERROR_00459 = 459,
+    VALIDATION_ERROR_00460 = 460,
+    VALIDATION_ERROR_00461 = 461,
+    VALIDATION_ERROR_00462 = 462,
+    VALIDATION_ERROR_00463 = 463,
+    VALIDATION_ERROR_00464 = 464,
+    VALIDATION_ERROR_00465 = 465,
+    VALIDATION_ERROR_00466 = 466,
+    VALIDATION_ERROR_00467 = 467,
+    VALIDATION_ERROR_00468 = 468,
+    VALIDATION_ERROR_00469 = 469,
+    VALIDATION_ERROR_00470 = 470,
+    VALIDATION_ERROR_00471 = 471,
+    VALIDATION_ERROR_00472 = 472,
+    VALIDATION_ERROR_00473 = 473,
+    VALIDATION_ERROR_00474 = 474,
+    VALIDATION_ERROR_00475 = 475,
+    VALIDATION_ERROR_00476 = 476,
+    VALIDATION_ERROR_00477 = 477,
+    VALIDATION_ERROR_00478 = 478,
+    VALIDATION_ERROR_00479 = 479,
+    VALIDATION_ERROR_00480 = 480,
+    VALIDATION_ERROR_00481 = 481,
+    VALIDATION_ERROR_00482 = 482,
+    VALIDATION_ERROR_00483 = 483,
+    VALIDATION_ERROR_00484 = 484,
+    VALIDATION_ERROR_00485 = 485,
+    VALIDATION_ERROR_00486 = 486,
+    VALIDATION_ERROR_00487 = 487,
+    VALIDATION_ERROR_00488 = 488,
+    VALIDATION_ERROR_00489 = 489,
+    VALIDATION_ERROR_00490 = 490,
+    VALIDATION_ERROR_00491 = 491,
+    VALIDATION_ERROR_00492 = 492,
+    VALIDATION_ERROR_00493 = 493,
+    VALIDATION_ERROR_00494 = 494,
+    VALIDATION_ERROR_00495 = 495,
+    VALIDATION_ERROR_00496 = 496,
+    VALIDATION_ERROR_00497 = 497,
+    VALIDATION_ERROR_00498 = 498,
+    VALIDATION_ERROR_00499 = 499,
+    VALIDATION_ERROR_00500 = 500,
+    VALIDATION_ERROR_00501 = 501,
+    VALIDATION_ERROR_00502 = 502,
+    VALIDATION_ERROR_00503 = 503,
+    VALIDATION_ERROR_00504 = 504,
+    VALIDATION_ERROR_00505 = 505,
+    VALIDATION_ERROR_00506 = 506,
+    VALIDATION_ERROR_00507 = 507,
+    VALIDATION_ERROR_00508 = 508,
+    VALIDATION_ERROR_00509 = 509,
+    VALIDATION_ERROR_00510 = 510,
+    VALIDATION_ERROR_00511 = 511,
+    VALIDATION_ERROR_00512 = 512,
+    VALIDATION_ERROR_00513 = 513,
+    VALIDATION_ERROR_00514 = 514,
+    VALIDATION_ERROR_00515 = 515,
+    VALIDATION_ERROR_00516 = 516,
+    VALIDATION_ERROR_00517 = 517,
+    VALIDATION_ERROR_00518 = 518,
+    VALIDATION_ERROR_00519 = 519,
+    VALIDATION_ERROR_00520 = 520,
+    VALIDATION_ERROR_00521 = 521,
+    VALIDATION_ERROR_00522 = 522,
+    VALIDATION_ERROR_00523 = 523,
+    VALIDATION_ERROR_00524 = 524,
+    VALIDATION_ERROR_00525 = 525,
+    VALIDATION_ERROR_00526 = 526,
+    VALIDATION_ERROR_00527 = 527,
+    VALIDATION_ERROR_00528 = 528,
+    VALIDATION_ERROR_00529 = 529,
+    VALIDATION_ERROR_00530 = 530,
+    VALIDATION_ERROR_00531 = 531,
+    VALIDATION_ERROR_00532 = 532,
+    VALIDATION_ERROR_00533 = 533,
+    VALIDATION_ERROR_00534 = 534,
+    VALIDATION_ERROR_00535 = 535,
+    VALIDATION_ERROR_00536 = 536,
+    VALIDATION_ERROR_00537 = 537,
+    VALIDATION_ERROR_00538 = 538,
+    VALIDATION_ERROR_00539 = 539,
+    VALIDATION_ERROR_00540 = 540,
+    VALIDATION_ERROR_00541 = 541,
+    VALIDATION_ERROR_00542 = 542,
+    VALIDATION_ERROR_00543 = 543,
+    VALIDATION_ERROR_00544 = 544,
+    VALIDATION_ERROR_00545 = 545,
+    VALIDATION_ERROR_00546 = 546,
+    VALIDATION_ERROR_00547 = 547,
+    VALIDATION_ERROR_00548 = 548,
+    VALIDATION_ERROR_00549 = 549,
+    VALIDATION_ERROR_00550 = 550,
+    VALIDATION_ERROR_00551 = 551,
+    VALIDATION_ERROR_00552 = 552,
+    VALIDATION_ERROR_00553 = 553,
+    VALIDATION_ERROR_00554 = 554,
+    VALIDATION_ERROR_00555 = 555,
+    VALIDATION_ERROR_00556 = 556,
+    VALIDATION_ERROR_00557 = 557,
+    VALIDATION_ERROR_00558 = 558,
+    VALIDATION_ERROR_00559 = 559,
+    VALIDATION_ERROR_00560 = 560,
+    VALIDATION_ERROR_00561 = 561,
+    VALIDATION_ERROR_00562 = 562,
+    VALIDATION_ERROR_00563 = 563,
+    VALIDATION_ERROR_00564 = 564,
+    VALIDATION_ERROR_00565 = 565,
+    VALIDATION_ERROR_00566 = 566,
+    VALIDATION_ERROR_00567 = 567,
+    VALIDATION_ERROR_00568 = 568,
+    VALIDATION_ERROR_00569 = 569,
+    VALIDATION_ERROR_00570 = 570,
+    VALIDATION_ERROR_00571 = 571,
+    VALIDATION_ERROR_00572 = 572,
+    VALIDATION_ERROR_00573 = 573,
+    VALIDATION_ERROR_00574 = 574,
+    VALIDATION_ERROR_00575 = 575,
+    VALIDATION_ERROR_00576 = 576,
+    VALIDATION_ERROR_00577 = 577,
+    VALIDATION_ERROR_00578 = 578,
+    VALIDATION_ERROR_00579 = 579,
+    VALIDATION_ERROR_00580 = 580,
+    VALIDATION_ERROR_00581 = 581,
+    VALIDATION_ERROR_00582 = 582,
+    VALIDATION_ERROR_00583 = 583,
+    VALIDATION_ERROR_00584 = 584,
+    VALIDATION_ERROR_00585 = 585,
+    VALIDATION_ERROR_00586 = 586,
+    VALIDATION_ERROR_00587 = 587,
+    VALIDATION_ERROR_00588 = 588,
+    VALIDATION_ERROR_00589 = 589,
+    VALIDATION_ERROR_00590 = 590,
+    VALIDATION_ERROR_00591 = 591,
+    VALIDATION_ERROR_00592 = 592,
+    VALIDATION_ERROR_00593 = 593,
+    VALIDATION_ERROR_00594 = 594,
+    VALIDATION_ERROR_00595 = 595,
+    VALIDATION_ERROR_00596 = 596,
+    VALIDATION_ERROR_00597 = 597,
+    VALIDATION_ERROR_00598 = 598,
+    VALIDATION_ERROR_00599 = 599,
+    VALIDATION_ERROR_00600 = 600,
+    VALIDATION_ERROR_00601 = 601,
+    VALIDATION_ERROR_00602 = 602,
+    VALIDATION_ERROR_00603 = 603,
+    VALIDATION_ERROR_00604 = 604,
+    VALIDATION_ERROR_00605 = 605,
+    VALIDATION_ERROR_00606 = 606,
+    VALIDATION_ERROR_00607 = 607,
+    VALIDATION_ERROR_00608 = 608,
+    VALIDATION_ERROR_00609 = 609,
+    VALIDATION_ERROR_00610 = 610,
+    VALIDATION_ERROR_00611 = 611,
+    VALIDATION_ERROR_00612 = 612,
+    VALIDATION_ERROR_00613 = 613,
+    VALIDATION_ERROR_00614 = 614,
+    VALIDATION_ERROR_00615 = 615,
+    VALIDATION_ERROR_00616 = 616,
+    VALIDATION_ERROR_00617 = 617,
+    VALIDATION_ERROR_00618 = 618,
+    VALIDATION_ERROR_00619 = 619,
+    VALIDATION_ERROR_00620 = 620,
+    VALIDATION_ERROR_00621 = 621,
+    VALIDATION_ERROR_00622 = 622,
+    VALIDATION_ERROR_00623 = 623,
+    VALIDATION_ERROR_00624 = 624,
+    VALIDATION_ERROR_00625 = 625,
+    VALIDATION_ERROR_00626 = 626,
+    VALIDATION_ERROR_00627 = 627,
+    VALIDATION_ERROR_00628 = 628,
+    VALIDATION_ERROR_00629 = 629,
+    VALIDATION_ERROR_00630 = 630,
+    VALIDATION_ERROR_00631 = 631,
+    VALIDATION_ERROR_00632 = 632,
+    VALIDATION_ERROR_00633 = 633,
+    VALIDATION_ERROR_00634 = 634,
+    VALIDATION_ERROR_00635 = 635,
+    VALIDATION_ERROR_00636 = 636,
+    VALIDATION_ERROR_00637 = 637,
+    VALIDATION_ERROR_00638 = 638,
+    VALIDATION_ERROR_00639 = 639,
+    VALIDATION_ERROR_00640 = 640,
+    VALIDATION_ERROR_00641 = 641,
+    VALIDATION_ERROR_00642 = 642,
+    VALIDATION_ERROR_00643 = 643,
+    VALIDATION_ERROR_00644 = 644,
+    VALIDATION_ERROR_00645 = 645,
+    VALIDATION_ERROR_00646 = 646,
+    VALIDATION_ERROR_00647 = 647,
+    VALIDATION_ERROR_00648 = 648,
+    VALIDATION_ERROR_00649 = 649,
+    VALIDATION_ERROR_00650 = 650,
+    VALIDATION_ERROR_00651 = 651,
+    VALIDATION_ERROR_00652 = 652,
+    VALIDATION_ERROR_00653 = 653,
+    VALIDATION_ERROR_00654 = 654,
+    VALIDATION_ERROR_00655 = 655,
+    VALIDATION_ERROR_00656 = 656,
+    VALIDATION_ERROR_00657 = 657,
+    VALIDATION_ERROR_00658 = 658,
+    VALIDATION_ERROR_00659 = 659,
+    VALIDATION_ERROR_00660 = 660,
+    VALIDATION_ERROR_00661 = 661,
+    VALIDATION_ERROR_00662 = 662,
+    VALIDATION_ERROR_00663 = 663,
+    VALIDATION_ERROR_00664 = 664,
+    VALIDATION_ERROR_00665 = 665,
+    VALIDATION_ERROR_00666 = 666,
+    VALIDATION_ERROR_00667 = 667,
+    VALIDATION_ERROR_00668 = 668,
+    VALIDATION_ERROR_00669 = 669,
+    VALIDATION_ERROR_00670 = 670,
+    VALIDATION_ERROR_00671 = 671,
+    VALIDATION_ERROR_00672 = 672,
+    VALIDATION_ERROR_00673 = 673,
+    VALIDATION_ERROR_00674 = 674,
+    VALIDATION_ERROR_00675 = 675,
+    VALIDATION_ERROR_00676 = 676,
+    VALIDATION_ERROR_00677 = 677,
+    VALIDATION_ERROR_00678 = 678,
+    VALIDATION_ERROR_00679 = 679,
+    VALIDATION_ERROR_00680 = 680,
+    VALIDATION_ERROR_00681 = 681,
+    VALIDATION_ERROR_00682 = 682,
+    VALIDATION_ERROR_00683 = 683,
+    VALIDATION_ERROR_00684 = 684,
+    VALIDATION_ERROR_00685 = 685,
+    VALIDATION_ERROR_00686 = 686,
+    VALIDATION_ERROR_00687 = 687,
+    VALIDATION_ERROR_00688 = 688,
+    VALIDATION_ERROR_00689 = 689,
+    VALIDATION_ERROR_00690 = 690,
+    VALIDATION_ERROR_00691 = 691,
+    VALIDATION_ERROR_00692 = 692,
+    VALIDATION_ERROR_00693 = 693,
+    VALIDATION_ERROR_00694 = 694,
+    VALIDATION_ERROR_00695 = 695,
+    VALIDATION_ERROR_00696 = 696,
+    VALIDATION_ERROR_00697 = 697,
+    VALIDATION_ERROR_00698 = 698,
+    VALIDATION_ERROR_00699 = 699,
+    VALIDATION_ERROR_00700 = 700,
+    VALIDATION_ERROR_00701 = 701,
+    VALIDATION_ERROR_00702 = 702,
+    VALIDATION_ERROR_00703 = 703,
+    VALIDATION_ERROR_00704 = 704,
+    VALIDATION_ERROR_00705 = 705,
+    VALIDATION_ERROR_00706 = 706,
+    VALIDATION_ERROR_00707 = 707,
+    VALIDATION_ERROR_00708 = 708,
+    VALIDATION_ERROR_00709 = 709,
+    VALIDATION_ERROR_00710 = 710,
+    VALIDATION_ERROR_00711 = 711,
+    VALIDATION_ERROR_00712 = 712,
+    VALIDATION_ERROR_00713 = 713,
+    VALIDATION_ERROR_00714 = 714,
+    VALIDATION_ERROR_00715 = 715,
+    VALIDATION_ERROR_00716 = 716,
+    VALIDATION_ERROR_00717 = 717,
+    VALIDATION_ERROR_00718 = 718,
+    VALIDATION_ERROR_00719 = 719,
+    VALIDATION_ERROR_00720 = 720,
+    VALIDATION_ERROR_00721 = 721,
+    VALIDATION_ERROR_00722 = 722,
+    VALIDATION_ERROR_00723 = 723,
+    VALIDATION_ERROR_00724 = 724,
+    VALIDATION_ERROR_00725 = 725,
+    VALIDATION_ERROR_00726 = 726,
+    VALIDATION_ERROR_00727 = 727,
+    VALIDATION_ERROR_00728 = 728,
+    VALIDATION_ERROR_00729 = 729,
+    VALIDATION_ERROR_00730 = 730,
+    VALIDATION_ERROR_00731 = 731,
+    VALIDATION_ERROR_00732 = 732,
+    VALIDATION_ERROR_00733 = 733,
+    VALIDATION_ERROR_00734 = 734,
+    VALIDATION_ERROR_00735 = 735,
+    VALIDATION_ERROR_00736 = 736,
+    VALIDATION_ERROR_00737 = 737,
+    VALIDATION_ERROR_00738 = 738,
+    VALIDATION_ERROR_00739 = 739,
+    VALIDATION_ERROR_00740 = 740,
+    VALIDATION_ERROR_00741 = 741,
+    VALIDATION_ERROR_00742 = 742,
+    VALIDATION_ERROR_00743 = 743,
+    VALIDATION_ERROR_00744 = 744,
+    VALIDATION_ERROR_00745 = 745,
+    VALIDATION_ERROR_00746 = 746,
+    VALIDATION_ERROR_00747 = 747,
+    VALIDATION_ERROR_00748 = 748,
+    VALIDATION_ERROR_00749 = 749,
+    VALIDATION_ERROR_00750 = 750,
+    VALIDATION_ERROR_00751 = 751,
+    VALIDATION_ERROR_00752 = 752,
+    VALIDATION_ERROR_00753 = 753,
+    VALIDATION_ERROR_00754 = 754,
+    VALIDATION_ERROR_00755 = 755,
+    VALIDATION_ERROR_00756 = 756,
+    VALIDATION_ERROR_00757 = 757,
+    VALIDATION_ERROR_00758 = 758,
+    VALIDATION_ERROR_00759 = 759,
+    VALIDATION_ERROR_00760 = 760,
+    VALIDATION_ERROR_00761 = 761,
+    VALIDATION_ERROR_00762 = 762,
+    VALIDATION_ERROR_00763 = 763,
+    VALIDATION_ERROR_00764 = 764,
+    VALIDATION_ERROR_00765 = 765,
+    VALIDATION_ERROR_00766 = 766,
+    VALIDATION_ERROR_00767 = 767,
+    VALIDATION_ERROR_00768 = 768,
+    VALIDATION_ERROR_00769 = 769,
+    VALIDATION_ERROR_00770 = 770,
+    VALIDATION_ERROR_00771 = 771,
+    VALIDATION_ERROR_00772 = 772,
+    VALIDATION_ERROR_00773 = 773,
+    VALIDATION_ERROR_00774 = 774,
+    VALIDATION_ERROR_00775 = 775,
+    VALIDATION_ERROR_00776 = 776,
+    VALIDATION_ERROR_00777 = 777,
+    VALIDATION_ERROR_00778 = 778,
+    VALIDATION_ERROR_00779 = 779,
+    VALIDATION_ERROR_00780 = 780,
+    VALIDATION_ERROR_00781 = 781,
+    VALIDATION_ERROR_00782 = 782,
+    VALIDATION_ERROR_00783 = 783,
+    VALIDATION_ERROR_00784 = 784,
+    VALIDATION_ERROR_00785 = 785,
+    VALIDATION_ERROR_00786 = 786,
+    VALIDATION_ERROR_00787 = 787,
+    VALIDATION_ERROR_00788 = 788,
+    VALIDATION_ERROR_00789 = 789,
+    VALIDATION_ERROR_00790 = 790,
+    VALIDATION_ERROR_00791 = 791,
+    VALIDATION_ERROR_00792 = 792,
+    VALIDATION_ERROR_00793 = 793,
+    VALIDATION_ERROR_00794 = 794,
+    VALIDATION_ERROR_00795 = 795,
+    VALIDATION_ERROR_00796 = 796,
+    VALIDATION_ERROR_00797 = 797,
+    VALIDATION_ERROR_00798 = 798,
+    VALIDATION_ERROR_00799 = 799,
+    VALIDATION_ERROR_00800 = 800,
+    VALIDATION_ERROR_00801 = 801,
+    VALIDATION_ERROR_00802 = 802,
+    VALIDATION_ERROR_00803 = 803,
+    VALIDATION_ERROR_00804 = 804,
+    VALIDATION_ERROR_00805 = 805,
+    VALIDATION_ERROR_00806 = 806,
+    VALIDATION_ERROR_00807 = 807,
+    VALIDATION_ERROR_00808 = 808,
+    VALIDATION_ERROR_00809 = 809,
+    VALIDATION_ERROR_00810 = 810,
+    VALIDATION_ERROR_00811 = 811,
+    VALIDATION_ERROR_00812 = 812,
+    VALIDATION_ERROR_00813 = 813,
+    VALIDATION_ERROR_00814 = 814,
+    VALIDATION_ERROR_00815 = 815,
+    VALIDATION_ERROR_00816 = 816,
+    VALIDATION_ERROR_00817 = 817,
+    VALIDATION_ERROR_00818 = 818,
+    VALIDATION_ERROR_00819 = 819,
+    VALIDATION_ERROR_00820 = 820,
+    VALIDATION_ERROR_00821 = 821,
+    VALIDATION_ERROR_00822 = 822,
+    VALIDATION_ERROR_00823 = 823,
+    VALIDATION_ERROR_00824 = 824,
+    VALIDATION_ERROR_00825 = 825,
+    VALIDATION_ERROR_00826 = 826,
+    VALIDATION_ERROR_00827 = 827,
+    VALIDATION_ERROR_00828 = 828,
+    VALIDATION_ERROR_00829 = 829,
+    VALIDATION_ERROR_00830 = 830,
+    VALIDATION_ERROR_00831 = 831,
+    VALIDATION_ERROR_00832 = 832,
+    VALIDATION_ERROR_00833 = 833,
+    VALIDATION_ERROR_00834 = 834,
+    VALIDATION_ERROR_00835 = 835,
+    VALIDATION_ERROR_00836 = 836,
+    VALIDATION_ERROR_00837 = 837,
+    VALIDATION_ERROR_00838 = 838,
+    VALIDATION_ERROR_00839 = 839,
+    VALIDATION_ERROR_00840 = 840,
+    VALIDATION_ERROR_00841 = 841,
+    VALIDATION_ERROR_00842 = 842,
+    VALIDATION_ERROR_00843 = 843,
+    VALIDATION_ERROR_00844 = 844,
+    VALIDATION_ERROR_00845 = 845,
+    VALIDATION_ERROR_00846 = 846,
+    VALIDATION_ERROR_00847 = 847,
+    VALIDATION_ERROR_00848 = 848,
+    VALIDATION_ERROR_00849 = 849,
+    VALIDATION_ERROR_00850 = 850,
+    VALIDATION_ERROR_00851 = 851,
+    VALIDATION_ERROR_00852 = 852,
+    VALIDATION_ERROR_00853 = 853,
+    VALIDATION_ERROR_00854 = 854,
+    VALIDATION_ERROR_00855 = 855,
+    VALIDATION_ERROR_00856 = 856,
+    VALIDATION_ERROR_00857 = 857,
+    VALIDATION_ERROR_00858 = 858,
+    VALIDATION_ERROR_00859 = 859,
+    VALIDATION_ERROR_00860 = 860,
+    VALIDATION_ERROR_00861 = 861,
+    VALIDATION_ERROR_00862 = 862,
+    VALIDATION_ERROR_00863 = 863,
+    VALIDATION_ERROR_00864 = 864,
+    VALIDATION_ERROR_00865 = 865,
+    VALIDATION_ERROR_00866 = 866,
+    VALIDATION_ERROR_00867 = 867,
+    VALIDATION_ERROR_00868 = 868,
+    VALIDATION_ERROR_00869 = 869,
+    VALIDATION_ERROR_00870 = 870,
+    VALIDATION_ERROR_00871 = 871,
+    VALIDATION_ERROR_00872 = 872,
+    VALIDATION_ERROR_00873 = 873,
+    VALIDATION_ERROR_00874 = 874,
+    VALIDATION_ERROR_00875 = 875,
+    VALIDATION_ERROR_00876 = 876,
+    VALIDATION_ERROR_00877 = 877,
+    VALIDATION_ERROR_00878 = 878,
+    VALIDATION_ERROR_00879 = 879,
+    VALIDATION_ERROR_00880 = 880,
+    VALIDATION_ERROR_00881 = 881,
+    VALIDATION_ERROR_00882 = 882,
+    VALIDATION_ERROR_00883 = 883,
+    VALIDATION_ERROR_00884 = 884,
+    VALIDATION_ERROR_00885 = 885,
+    VALIDATION_ERROR_00886 = 886,
+    VALIDATION_ERROR_00887 = 887,
+    VALIDATION_ERROR_00888 = 888,
+    VALIDATION_ERROR_00889 = 889,
+    VALIDATION_ERROR_00890 = 890,
+    VALIDATION_ERROR_00891 = 891,
+    VALIDATION_ERROR_00892 = 892,
+    VALIDATION_ERROR_00893 = 893,
+    VALIDATION_ERROR_00894 = 894,
+    VALIDATION_ERROR_00895 = 895,
+    VALIDATION_ERROR_00896 = 896,
+    VALIDATION_ERROR_00897 = 897,
+    VALIDATION_ERROR_00898 = 898,
+    VALIDATION_ERROR_00899 = 899,
+    VALIDATION_ERROR_00900 = 900,
+    VALIDATION_ERROR_00901 = 901,
+    VALIDATION_ERROR_00902 = 902,
+    VALIDATION_ERROR_00903 = 903,
+    VALIDATION_ERROR_00904 = 904,
+    VALIDATION_ERROR_00905 = 905,
+    VALIDATION_ERROR_00906 = 906,
+    VALIDATION_ERROR_00907 = 907,
+    VALIDATION_ERROR_00908 = 908,
+    VALIDATION_ERROR_00909 = 909,
+    VALIDATION_ERROR_00910 = 910,
+    VALIDATION_ERROR_00911 = 911,
+    VALIDATION_ERROR_00912 = 912,
+    VALIDATION_ERROR_00913 = 913,
+    VALIDATION_ERROR_00914 = 914,
+    VALIDATION_ERROR_00915 = 915,
+    VALIDATION_ERROR_00916 = 916,
+    VALIDATION_ERROR_00917 = 917,
+    VALIDATION_ERROR_00918 = 918,
+    VALIDATION_ERROR_00919 = 919,
+    VALIDATION_ERROR_00920 = 920,
+    VALIDATION_ERROR_00921 = 921,
+    VALIDATION_ERROR_00922 = 922,
+    VALIDATION_ERROR_00923 = 923,
+    VALIDATION_ERROR_00924 = 924,
+    VALIDATION_ERROR_00925 = 925,
+    VALIDATION_ERROR_00926 = 926,
+    VALIDATION_ERROR_00927 = 927,
+    VALIDATION_ERROR_00928 = 928,
+    VALIDATION_ERROR_00929 = 929,
+    VALIDATION_ERROR_00930 = 930,
+    VALIDATION_ERROR_00931 = 931,
+    VALIDATION_ERROR_00932 = 932,
+    VALIDATION_ERROR_00933 = 933,
+    VALIDATION_ERROR_00934 = 934,
+    VALIDATION_ERROR_00935 = 935,
+    VALIDATION_ERROR_00936 = 936,
+    VALIDATION_ERROR_00937 = 937,
+    VALIDATION_ERROR_00938 = 938,
+    VALIDATION_ERROR_00939 = 939,
+    VALIDATION_ERROR_00940 = 940,
+    VALIDATION_ERROR_00941 = 941,
+    VALIDATION_ERROR_00942 = 942,
+    VALIDATION_ERROR_00943 = 943,
+    VALIDATION_ERROR_00944 = 944,
+    VALIDATION_ERROR_00945 = 945,
+    VALIDATION_ERROR_00946 = 946,
+    VALIDATION_ERROR_00947 = 947,
+    VALIDATION_ERROR_00948 = 948,
+    VALIDATION_ERROR_00949 = 949,
+    VALIDATION_ERROR_00950 = 950,
+    VALIDATION_ERROR_00951 = 951,
+    VALIDATION_ERROR_00952 = 952,
+    VALIDATION_ERROR_00953 = 953,
+    VALIDATION_ERROR_00954 = 954,
+    VALIDATION_ERROR_00955 = 955,
+    VALIDATION_ERROR_00956 = 956,
+    VALIDATION_ERROR_00957 = 957,
+    VALIDATION_ERROR_00958 = 958,
+    VALIDATION_ERROR_00959 = 959,
+    VALIDATION_ERROR_00960 = 960,
+    VALIDATION_ERROR_00961 = 961,
+    VALIDATION_ERROR_00962 = 962,
+    VALIDATION_ERROR_00963 = 963,
+    VALIDATION_ERROR_00964 = 964,
+    VALIDATION_ERROR_00965 = 965,
+    VALIDATION_ERROR_00966 = 966,
+    VALIDATION_ERROR_00967 = 967,
+    VALIDATION_ERROR_00968 = 968,
+    VALIDATION_ERROR_00969 = 969,
+    VALIDATION_ERROR_00970 = 970,
+    VALIDATION_ERROR_00971 = 971,
+    VALIDATION_ERROR_00972 = 972,
+    VALIDATION_ERROR_00973 = 973,
+    VALIDATION_ERROR_00974 = 974,
+    VALIDATION_ERROR_00975 = 975,
+    VALIDATION_ERROR_00976 = 976,
+    VALIDATION_ERROR_00977 = 977,
+    VALIDATION_ERROR_00978 = 978,
+    VALIDATION_ERROR_00979 = 979,
+    VALIDATION_ERROR_00980 = 980,
+    VALIDATION_ERROR_00981 = 981,
+    VALIDATION_ERROR_00982 = 982,
+    VALIDATION_ERROR_00983 = 983,
+    VALIDATION_ERROR_00984 = 984,
+    VALIDATION_ERROR_00985 = 985,
+    VALIDATION_ERROR_00986 = 986,
+    VALIDATION_ERROR_00987 = 987,
+    VALIDATION_ERROR_00988 = 988,
+    VALIDATION_ERROR_00989 = 989,
+    VALIDATION_ERROR_00990 = 990,
+    VALIDATION_ERROR_00991 = 991,
+    VALIDATION_ERROR_00992 = 992,
+    VALIDATION_ERROR_00993 = 993,
+    VALIDATION_ERROR_00994 = 994,
+    VALIDATION_ERROR_00995 = 995,
+    VALIDATION_ERROR_00996 = 996,
+    VALIDATION_ERROR_00997 = 997,
+    VALIDATION_ERROR_00998 = 998,
+    VALIDATION_ERROR_00999 = 999,
+    VALIDATION_ERROR_01000 = 1000,
+    VALIDATION_ERROR_01001 = 1001,
+    VALIDATION_ERROR_01002 = 1002,
+    VALIDATION_ERROR_01003 = 1003,
+    VALIDATION_ERROR_01004 = 1004,
+    VALIDATION_ERROR_01005 = 1005,
+    VALIDATION_ERROR_01006 = 1006,
+    VALIDATION_ERROR_01007 = 1007,
+    VALIDATION_ERROR_01008 = 1008,
+    VALIDATION_ERROR_01009 = 1009,
+    VALIDATION_ERROR_01010 = 1010,
+    VALIDATION_ERROR_01011 = 1011,
+    VALIDATION_ERROR_01012 = 1012,
+    VALIDATION_ERROR_01013 = 1013,
+    VALIDATION_ERROR_01014 = 1014,
+    VALIDATION_ERROR_01015 = 1015,
+    VALIDATION_ERROR_01016 = 1016,
+    VALIDATION_ERROR_01017 = 1017,
+    VALIDATION_ERROR_01018 = 1018,
+    VALIDATION_ERROR_01019 = 1019,
+    VALIDATION_ERROR_01020 = 1020,
+    VALIDATION_ERROR_01021 = 1021,
+    VALIDATION_ERROR_01022 = 1022,
+    VALIDATION_ERROR_01023 = 1023,
+    VALIDATION_ERROR_01024 = 1024,
+    VALIDATION_ERROR_01025 = 1025,
+    VALIDATION_ERROR_01026 = 1026,
+    VALIDATION_ERROR_01027 = 1027,
+    VALIDATION_ERROR_01028 = 1028,
+    VALIDATION_ERROR_01029 = 1029,
+    VALIDATION_ERROR_01030 = 1030,
+    VALIDATION_ERROR_01031 = 1031,
+    VALIDATION_ERROR_01032 = 1032,
+    VALIDATION_ERROR_01033 = 1033,
+    VALIDATION_ERROR_01034 = 1034,
+    VALIDATION_ERROR_01035 = 1035,
+    VALIDATION_ERROR_01036 = 1036,
+    VALIDATION_ERROR_01037 = 1037,
+    VALIDATION_ERROR_01038 = 1038,
+    VALIDATION_ERROR_01039 = 1039,
+    VALIDATION_ERROR_01040 = 1040,
+    VALIDATION_ERROR_01041 = 1041,
+    VALIDATION_ERROR_01042 = 1042,
+    VALIDATION_ERROR_01043 = 1043,
+    VALIDATION_ERROR_01044 = 1044,
+    VALIDATION_ERROR_01045 = 1045,
+    VALIDATION_ERROR_01046 = 1046,
+    VALIDATION_ERROR_01047 = 1047,
+    VALIDATION_ERROR_01048 = 1048,
+    VALIDATION_ERROR_01049 = 1049,
+    VALIDATION_ERROR_01050 = 1050,
+    VALIDATION_ERROR_01051 = 1051,
+    VALIDATION_ERROR_01052 = 1052,
+    VALIDATION_ERROR_01053 = 1053,
+    VALIDATION_ERROR_01054 = 1054,
+    VALIDATION_ERROR_01055 = 1055,
+    VALIDATION_ERROR_01056 = 1056,
+    VALIDATION_ERROR_01057 = 1057,
+    VALIDATION_ERROR_01058 = 1058,
+    VALIDATION_ERROR_01059 = 1059,
+    VALIDATION_ERROR_01060 = 1060,
+    VALIDATION_ERROR_01061 = 1061,
+    VALIDATION_ERROR_01062 = 1062,
+    VALIDATION_ERROR_01063 = 1063,
+    VALIDATION_ERROR_01064 = 1064,
+    VALIDATION_ERROR_01065 = 1065,
+    VALIDATION_ERROR_01066 = 1066,
+    VALIDATION_ERROR_01067 = 1067,
+    VALIDATION_ERROR_01068 = 1068,
+    VALIDATION_ERROR_01069 = 1069,
+    VALIDATION_ERROR_01070 = 1070,
+    VALIDATION_ERROR_01071 = 1071,
+    VALIDATION_ERROR_01072 = 1072,
+    VALIDATION_ERROR_01073 = 1073,
+    VALIDATION_ERROR_01074 = 1074,
+    VALIDATION_ERROR_01075 = 1075,
+    VALIDATION_ERROR_01076 = 1076,
+    VALIDATION_ERROR_01077 = 1077,
+    VALIDATION_ERROR_01078 = 1078,
+    VALIDATION_ERROR_01079 = 1079,
+    VALIDATION_ERROR_01080 = 1080,
+    VALIDATION_ERROR_01081 = 1081,
+    VALIDATION_ERROR_01082 = 1082,
+    VALIDATION_ERROR_01083 = 1083,
+    VALIDATION_ERROR_01084 = 1084,
+    VALIDATION_ERROR_01085 = 1085,
+    VALIDATION_ERROR_01086 = 1086,
+    VALIDATION_ERROR_01087 = 1087,
+    VALIDATION_ERROR_01088 = 1088,
+    VALIDATION_ERROR_01089 = 1089,
+    VALIDATION_ERROR_01090 = 1090,
+    VALIDATION_ERROR_01091 = 1091,
+    VALIDATION_ERROR_01092 = 1092,
+    VALIDATION_ERROR_01093 = 1093,
+    VALIDATION_ERROR_01094 = 1094,
+    VALIDATION_ERROR_01095 = 1095,
+    VALIDATION_ERROR_01096 = 1096,
+    VALIDATION_ERROR_01097 = 1097,
+    VALIDATION_ERROR_01098 = 1098,
+    VALIDATION_ERROR_01099 = 1099,
+    VALIDATION_ERROR_01100 = 1100,
+    VALIDATION_ERROR_01101 = 1101,
+    VALIDATION_ERROR_01102 = 1102,
+    VALIDATION_ERROR_01103 = 1103,
+    VALIDATION_ERROR_01104 = 1104,
+    VALIDATION_ERROR_01105 = 1105,
+    VALIDATION_ERROR_01106 = 1106,
+    VALIDATION_ERROR_01107 = 1107,
+    VALIDATION_ERROR_01108 = 1108,
+    VALIDATION_ERROR_01109 = 1109,
+    VALIDATION_ERROR_01110 = 1110,
+    VALIDATION_ERROR_01111 = 1111,
+    VALIDATION_ERROR_01112 = 1112,
+    VALIDATION_ERROR_01113 = 1113,
+    VALIDATION_ERROR_01114 = 1114,
+    VALIDATION_ERROR_01115 = 1115,
+    VALIDATION_ERROR_01116 = 1116,
+    VALIDATION_ERROR_01117 = 1117,
+    VALIDATION_ERROR_01118 = 1118,
+    VALIDATION_ERROR_01119 = 1119,
+    VALIDATION_ERROR_01120 = 1120,
+    VALIDATION_ERROR_01121 = 1121,
+    VALIDATION_ERROR_01122 = 1122,
+    VALIDATION_ERROR_01123 = 1123,
+    VALIDATION_ERROR_01124 = 1124,
+    VALIDATION_ERROR_01125 = 1125,
+    VALIDATION_ERROR_01126 = 1126,
+    VALIDATION_ERROR_01127 = 1127,
+    VALIDATION_ERROR_01128 = 1128,
+    VALIDATION_ERROR_01129 = 1129,
+    VALIDATION_ERROR_01130 = 1130,
+    VALIDATION_ERROR_01131 = 1131,
+    VALIDATION_ERROR_01132 = 1132,
+    VALIDATION_ERROR_01133 = 1133,
+    VALIDATION_ERROR_01134 = 1134,
+    VALIDATION_ERROR_01135 = 1135,
+    VALIDATION_ERROR_01136 = 1136,
+    VALIDATION_ERROR_01137 = 1137,
+    VALIDATION_ERROR_01138 = 1138,
+    VALIDATION_ERROR_01139 = 1139,
+    VALIDATION_ERROR_01140 = 1140,
+    VALIDATION_ERROR_01141 = 1141,
+    VALIDATION_ERROR_01142 = 1142,
+    VALIDATION_ERROR_01143 = 1143,
+    VALIDATION_ERROR_01144 = 1144,
+    VALIDATION_ERROR_01145 = 1145,
+    VALIDATION_ERROR_01146 = 1146,
+    VALIDATION_ERROR_01147 = 1147,
+    VALIDATION_ERROR_01148 = 1148,
+    VALIDATION_ERROR_01149 = 1149,
+    VALIDATION_ERROR_01150 = 1150,
+    VALIDATION_ERROR_01151 = 1151,
+    VALIDATION_ERROR_01152 = 1152,
+    VALIDATION_ERROR_01153 = 1153,
+    VALIDATION_ERROR_01154 = 1154,
+    VALIDATION_ERROR_01155 = 1155,
+    VALIDATION_ERROR_01156 = 1156,
+    VALIDATION_ERROR_01157 = 1157,
+    VALIDATION_ERROR_01158 = 1158,
+    VALIDATION_ERROR_01159 = 1159,
+    VALIDATION_ERROR_01160 = 1160,
+    VALIDATION_ERROR_01161 = 1161,
+    VALIDATION_ERROR_01162 = 1162,
+    VALIDATION_ERROR_01163 = 1163,
+    VALIDATION_ERROR_01164 = 1164,
+    VALIDATION_ERROR_01165 = 1165,
+    VALIDATION_ERROR_01166 = 1166,
+    VALIDATION_ERROR_01167 = 1167,
+    VALIDATION_ERROR_01168 = 1168,
+    VALIDATION_ERROR_01169 = 1169,
+    VALIDATION_ERROR_01170 = 1170,
+    VALIDATION_ERROR_01171 = 1171,
+    VALIDATION_ERROR_01172 = 1172,
+    VALIDATION_ERROR_01173 = 1173,
+    VALIDATION_ERROR_01174 = 1174,
+    VALIDATION_ERROR_01175 = 1175,
+    VALIDATION_ERROR_01176 = 1176,
+    VALIDATION_ERROR_01177 = 1177,
+    VALIDATION_ERROR_01178 = 1178,
+    VALIDATION_ERROR_01179 = 1179,
+    VALIDATION_ERROR_01180 = 1180,
+    VALIDATION_ERROR_01181 = 1181,
+    VALIDATION_ERROR_01182 = 1182,
+    VALIDATION_ERROR_01183 = 1183,
+    VALIDATION_ERROR_01184 = 1184,
+    VALIDATION_ERROR_01185 = 1185,
+    VALIDATION_ERROR_01186 = 1186,
+    VALIDATION_ERROR_01187 = 1187,
+    VALIDATION_ERROR_01188 = 1188,
+    VALIDATION_ERROR_01189 = 1189,
+    VALIDATION_ERROR_01190 = 1190,
+    VALIDATION_ERROR_01191 = 1191,
+    VALIDATION_ERROR_01192 = 1192,
+    VALIDATION_ERROR_01193 = 1193,
+    VALIDATION_ERROR_01194 = 1194,
+    VALIDATION_ERROR_01195 = 1195,
+    VALIDATION_ERROR_01196 = 1196,
+    VALIDATION_ERROR_01197 = 1197,
+    VALIDATION_ERROR_01198 = 1198,
+    VALIDATION_ERROR_01199 = 1199,
+    VALIDATION_ERROR_01200 = 1200,
+    VALIDATION_ERROR_01201 = 1201,
+    VALIDATION_ERROR_01202 = 1202,
+    VALIDATION_ERROR_01203 = 1203,
+    VALIDATION_ERROR_01204 = 1204,
+    VALIDATION_ERROR_01205 = 1205,
+    VALIDATION_ERROR_01206 = 1206,
+    VALIDATION_ERROR_01207 = 1207,
+    VALIDATION_ERROR_01208 = 1208,
+    VALIDATION_ERROR_01209 = 1209,
+    VALIDATION_ERROR_01210 = 1210,
+    VALIDATION_ERROR_01211 = 1211,
+    VALIDATION_ERROR_01212 = 1212,
+    VALIDATION_ERROR_01213 = 1213,
+    VALIDATION_ERROR_01214 = 1214,
+    VALIDATION_ERROR_01215 = 1215,
+    VALIDATION_ERROR_01216 = 1216,
+    VALIDATION_ERROR_01217 = 1217,
+    VALIDATION_ERROR_01218 = 1218,
+    VALIDATION_ERROR_01219 = 1219,
+    VALIDATION_ERROR_01220 = 1220,
+    VALIDATION_ERROR_01221 = 1221,
+    VALIDATION_ERROR_01222 = 1222,
+    VALIDATION_ERROR_01223 = 1223,
+    VALIDATION_ERROR_01224 = 1224,
+    VALIDATION_ERROR_01225 = 1225,
+    VALIDATION_ERROR_01226 = 1226,
+    VALIDATION_ERROR_01227 = 1227,
+    VALIDATION_ERROR_01228 = 1228,
+    VALIDATION_ERROR_01229 = 1229,
+    VALIDATION_ERROR_01230 = 1230,
+    VALIDATION_ERROR_01231 = 1231,
+    VALIDATION_ERROR_01232 = 1232,
+    VALIDATION_ERROR_01233 = 1233,
+    VALIDATION_ERROR_01234 = 1234,
+    VALIDATION_ERROR_01235 = 1235,
+    VALIDATION_ERROR_01236 = 1236,
+    VALIDATION_ERROR_01237 = 1237,
+    VALIDATION_ERROR_01238 = 1238,
+    VALIDATION_ERROR_01239 = 1239,
+    VALIDATION_ERROR_01240 = 1240,
+    VALIDATION_ERROR_01241 = 1241,
+    VALIDATION_ERROR_01242 = 1242,
+    VALIDATION_ERROR_01243 = 1243,
+    VALIDATION_ERROR_01244 = 1244,
+    VALIDATION_ERROR_01245 = 1245,
+    VALIDATION_ERROR_01246 = 1246,
+    VALIDATION_ERROR_01247 = 1247,
+    VALIDATION_ERROR_01248 = 1248,
+    VALIDATION_ERROR_01249 = 1249,
+    VALIDATION_ERROR_01250 = 1250,
+    VALIDATION_ERROR_01251 = 1251,
+    VALIDATION_ERROR_01252 = 1252,
+    VALIDATION_ERROR_01253 = 1253,
+    VALIDATION_ERROR_01254 = 1254,
+    VALIDATION_ERROR_01255 = 1255,
+    VALIDATION_ERROR_01256 = 1256,
+    VALIDATION_ERROR_01257 = 1257,
+    VALIDATION_ERROR_01258 = 1258,
+    VALIDATION_ERROR_01259 = 1259,
+    VALIDATION_ERROR_01260 = 1260,
+    VALIDATION_ERROR_01261 = 1261,
+    VALIDATION_ERROR_01262 = 1262,
+    VALIDATION_ERROR_01263 = 1263,
+    VALIDATION_ERROR_01264 = 1264,
+    VALIDATION_ERROR_01265 = 1265,
+    VALIDATION_ERROR_01266 = 1266,
+    VALIDATION_ERROR_01267 = 1267,
+    VALIDATION_ERROR_01268 = 1268,
+    VALIDATION_ERROR_01269 = 1269,
+    VALIDATION_ERROR_01270 = 1270,
+    VALIDATION_ERROR_01271 = 1271,
+    VALIDATION_ERROR_01272 = 1272,
+    VALIDATION_ERROR_01273 = 1273,
+    VALIDATION_ERROR_01274 = 1274,
+    VALIDATION_ERROR_01275 = 1275,
+    VALIDATION_ERROR_01276 = 1276,
+    VALIDATION_ERROR_01277 = 1277,
+    VALIDATION_ERROR_01278 = 1278,
+    VALIDATION_ERROR_01279 = 1279,
+    VALIDATION_ERROR_01280 = 1280,
+    VALIDATION_ERROR_01281 = 1281,
+    VALIDATION_ERROR_01282 = 1282,
+    VALIDATION_ERROR_01283 = 1283,
+    VALIDATION_ERROR_01287 = 1287,
+    VALIDATION_ERROR_01288 = 1288,
+    VALIDATION_ERROR_01289 = 1289,
+    VALIDATION_ERROR_01290 = 1290,
+    VALIDATION_ERROR_01291 = 1291,
+    VALIDATION_ERROR_01292 = 1292,
+    VALIDATION_ERROR_01293 = 1293,
+    VALIDATION_ERROR_01294 = 1294,
+    VALIDATION_ERROR_01295 = 1295,
+    VALIDATION_ERROR_01296 = 1296,
+    VALIDATION_ERROR_01297 = 1297,
+    VALIDATION_ERROR_01298 = 1298,
+    VALIDATION_ERROR_01299 = 1299,
+    VALIDATION_ERROR_01300 = 1300,
+    VALIDATION_ERROR_01301 = 1301,
+    VALIDATION_ERROR_01302 = 1302,
+    VALIDATION_ERROR_01303 = 1303,
+    VALIDATION_ERROR_01304 = 1304,
+    VALIDATION_ERROR_01305 = 1305,
+    VALIDATION_ERROR_01306 = 1306,
+    VALIDATION_ERROR_01307 = 1307,
+    VALIDATION_ERROR_01308 = 1308,
+    VALIDATION_ERROR_01309 = 1309,
+    VALIDATION_ERROR_01310 = 1310,
+    VALIDATION_ERROR_01311 = 1311,
+    VALIDATION_ERROR_01312 = 1312,
+    VALIDATION_ERROR_01313 = 1313,
+    VALIDATION_ERROR_01314 = 1314,
+    VALIDATION_ERROR_01315 = 1315,
+    VALIDATION_ERROR_01316 = 1316,
+    VALIDATION_ERROR_01317 = 1317,
+    VALIDATION_ERROR_01318 = 1318,
+    VALIDATION_ERROR_01319 = 1319,
+    VALIDATION_ERROR_01320 = 1320,
+    VALIDATION_ERROR_01321 = 1321,
+    VALIDATION_ERROR_01322 = 1322,
+    VALIDATION_ERROR_01323 = 1323,
+    VALIDATION_ERROR_01324 = 1324,
+    VALIDATION_ERROR_01325 = 1325,
+    VALIDATION_ERROR_01326 = 1326,
+    VALIDATION_ERROR_01327 = 1327,
+    VALIDATION_ERROR_01328 = 1328,
+    VALIDATION_ERROR_01329 = 1329,
+    VALIDATION_ERROR_01330 = 1330,
+    VALIDATION_ERROR_01331 = 1331,
+    VALIDATION_ERROR_01332 = 1332,
+    VALIDATION_ERROR_01333 = 1333,
+    VALIDATION_ERROR_01334 = 1334,
+    VALIDATION_ERROR_01335 = 1335,
+    VALIDATION_ERROR_01336 = 1336,
+    VALIDATION_ERROR_01337 = 1337,
+    VALIDATION_ERROR_01338 = 1338,
+    VALIDATION_ERROR_01339 = 1339,
+    VALIDATION_ERROR_01340 = 1340,
+    VALIDATION_ERROR_01341 = 1341,
+    VALIDATION_ERROR_01342 = 1342,
+    VALIDATION_ERROR_01343 = 1343,
+    VALIDATION_ERROR_01344 = 1344,
+    VALIDATION_ERROR_01345 = 1345,
+    VALIDATION_ERROR_01346 = 1346,
+    VALIDATION_ERROR_01347 = 1347,
+    VALIDATION_ERROR_01348 = 1348,
+    VALIDATION_ERROR_01349 = 1349,
+    VALIDATION_ERROR_01350 = 1350,
+    VALIDATION_ERROR_01351 = 1351,
+    VALIDATION_ERROR_01352 = 1352,
+    VALIDATION_ERROR_01353 = 1353,
+    VALIDATION_ERROR_01354 = 1354,
+    VALIDATION_ERROR_01355 = 1355,
+    VALIDATION_ERROR_01356 = 1356,
+    VALIDATION_ERROR_01357 = 1357,
+    VALIDATION_ERROR_01358 = 1358,
+    VALIDATION_ERROR_01359 = 1359,
+    VALIDATION_ERROR_01360 = 1360,
+    VALIDATION_ERROR_01361 = 1361,
+    VALIDATION_ERROR_01362 = 1362,
+    VALIDATION_ERROR_01363 = 1363,
+    VALIDATION_ERROR_01364 = 1364,
+    VALIDATION_ERROR_01365 = 1365,
+    VALIDATION_ERROR_01366 = 1366,
+    VALIDATION_ERROR_01367 = 1367,
+    VALIDATION_ERROR_01368 = 1368,
+    VALIDATION_ERROR_01369 = 1369,
+    VALIDATION_ERROR_01370 = 1370,
+    VALIDATION_ERROR_01371 = 1371,
+    VALIDATION_ERROR_01372 = 1372,
+    VALIDATION_ERROR_01373 = 1373,
+    VALIDATION_ERROR_01374 = 1374,
+    VALIDATION_ERROR_01375 = 1375,
+    VALIDATION_ERROR_01376 = 1376,
+    VALIDATION_ERROR_01377 = 1377,
+    VALIDATION_ERROR_01378 = 1378,
+    VALIDATION_ERROR_01379 = 1379,
+    VALIDATION_ERROR_01380 = 1380,
+    VALIDATION_ERROR_01381 = 1381,
+    VALIDATION_ERROR_01382 = 1382,
+    VALIDATION_ERROR_01383 = 1383,
+    VALIDATION_ERROR_01384 = 1384,
+    VALIDATION_ERROR_01385 = 1385,
+    VALIDATION_ERROR_01386 = 1386,
+    VALIDATION_ERROR_01387 = 1387,
+    VALIDATION_ERROR_01388 = 1388,
+    VALIDATION_ERROR_01389 = 1389,
+    VALIDATION_ERROR_01390 = 1390,
+    VALIDATION_ERROR_01391 = 1391,
+    VALIDATION_ERROR_01392 = 1392,
+    VALIDATION_ERROR_01393 = 1393,
+    VALIDATION_ERROR_01394 = 1394,
+    VALIDATION_ERROR_01395 = 1395,
+    VALIDATION_ERROR_01396 = 1396,
+    VALIDATION_ERROR_01397 = 1397,
+    VALIDATION_ERROR_01398 = 1398,
+    VALIDATION_ERROR_01399 = 1399,
+    VALIDATION_ERROR_01400 = 1400,
+    VALIDATION_ERROR_01401 = 1401,
+    VALIDATION_ERROR_01402 = 1402,
+    VALIDATION_ERROR_01403 = 1403,
+    VALIDATION_ERROR_01404 = 1404,
+    VALIDATION_ERROR_01405 = 1405,
+    VALIDATION_ERROR_01406 = 1406,
+    VALIDATION_ERROR_01407 = 1407,
+    VALIDATION_ERROR_01408 = 1408,
+    VALIDATION_ERROR_01409 = 1409,
+    VALIDATION_ERROR_01410 = 1410,
+    VALIDATION_ERROR_01411 = 1411,
+    VALIDATION_ERROR_01412 = 1412,
+    VALIDATION_ERROR_01413 = 1413,
+    VALIDATION_ERROR_01414 = 1414,
+    VALIDATION_ERROR_01415 = 1415,
+    VALIDATION_ERROR_01416 = 1416,
+    VALIDATION_ERROR_01417 = 1417,
+    VALIDATION_ERROR_01418 = 1418,
+    VALIDATION_ERROR_01419 = 1419,
+    VALIDATION_ERROR_01420 = 1420,
+    VALIDATION_ERROR_01421 = 1421,
+    VALIDATION_ERROR_01422 = 1422,
+    VALIDATION_ERROR_01423 = 1423,
+    VALIDATION_ERROR_01424 = 1424,
+    VALIDATION_ERROR_01425 = 1425,
+    VALIDATION_ERROR_01426 = 1426,
+    VALIDATION_ERROR_01427 = 1427,
+    VALIDATION_ERROR_01428 = 1428,
+    VALIDATION_ERROR_01429 = 1429,
+    VALIDATION_ERROR_01430 = 1430,
+    VALIDATION_ERROR_01431 = 1431,
+    VALIDATION_ERROR_01432 = 1432,
+    VALIDATION_ERROR_01433 = 1433,
+    VALIDATION_ERROR_01434 = 1434,
+    VALIDATION_ERROR_01435 = 1435,
+    VALIDATION_ERROR_01436 = 1436,
+    VALIDATION_ERROR_01437 = 1437,
+    VALIDATION_ERROR_01438 = 1438,
+    VALIDATION_ERROR_01439 = 1439,
+    VALIDATION_ERROR_01440 = 1440,
+    VALIDATION_ERROR_01441 = 1441,
+    VALIDATION_ERROR_01442 = 1442,
+    VALIDATION_ERROR_01443 = 1443,
+    VALIDATION_ERROR_01444 = 1444,
+    VALIDATION_ERROR_01445 = 1445,
+    VALIDATION_ERROR_01446 = 1446,
+    VALIDATION_ERROR_01447 = 1447,
+    VALIDATION_ERROR_01448 = 1448,
+    VALIDATION_ERROR_01449 = 1449,
+    VALIDATION_ERROR_01450 = 1450,
+    VALIDATION_ERROR_01451 = 1451,
+    VALIDATION_ERROR_01452 = 1452,
+    VALIDATION_ERROR_01453 = 1453,
+    VALIDATION_ERROR_01454 = 1454,
+    VALIDATION_ERROR_01455 = 1455,
+    VALIDATION_ERROR_01456 = 1456,
+    VALIDATION_ERROR_01457 = 1457,
+    VALIDATION_ERROR_01458 = 1458,
+    VALIDATION_ERROR_01459 = 1459,
+    VALIDATION_ERROR_01460 = 1460,
+    VALIDATION_ERROR_01461 = 1461,
+    VALIDATION_ERROR_01462 = 1462,
+    VALIDATION_ERROR_01463 = 1463,
+    VALIDATION_ERROR_01464 = 1464,
+    VALIDATION_ERROR_01465 = 1465,
+    VALIDATION_ERROR_01466 = 1466,
+    VALIDATION_ERROR_01467 = 1467,
+    VALIDATION_ERROR_01468 = 1468,
+    VALIDATION_ERROR_01469 = 1469,
+    VALIDATION_ERROR_01470 = 1470,
+    VALIDATION_ERROR_01476 = 1476,
+    VALIDATION_ERROR_01477 = 1477,
+    VALIDATION_ERROR_01478 = 1478,
+    VALIDATION_ERROR_01479 = 1479,
+    VALIDATION_ERROR_01480 = 1480,
+    VALIDATION_ERROR_01481 = 1481,
+    VALIDATION_ERROR_01482 = 1482,
+    VALIDATION_ERROR_01483 = 1483,
+    VALIDATION_ERROR_01484 = 1484,
+    VALIDATION_ERROR_01485 = 1485,
+    VALIDATION_ERROR_01486 = 1486,
+    VALIDATION_ERROR_01487 = 1487,
+    VALIDATION_ERROR_01488 = 1488,
+    VALIDATION_ERROR_01489 = 1489,
+    VALIDATION_ERROR_01490 = 1490,
+    VALIDATION_ERROR_01491 = 1491,
+    VALIDATION_ERROR_01492 = 1492,
+    VALIDATION_ERROR_01493 = 1493,
+    VALIDATION_ERROR_01494 = 1494,
+    VALIDATION_ERROR_01495 = 1495,
+    VALIDATION_ERROR_01496 = 1496,
+    VALIDATION_ERROR_01497 = 1497,
+    VALIDATION_ERROR_01498 = 1498,
+    VALIDATION_ERROR_01499 = 1499,
+    VALIDATION_ERROR_01500 = 1500,
+    VALIDATION_ERROR_01501 = 1501,
+    VALIDATION_ERROR_01502 = 1502,
+    VALIDATION_ERROR_01503 = 1503,
+    VALIDATION_ERROR_01504 = 1504,
+    VALIDATION_ERROR_01505 = 1505,
+    VALIDATION_ERROR_01506 = 1506,
+    VALIDATION_ERROR_01507 = 1507,
+    VALIDATION_ERROR_01508 = 1508,
+    VALIDATION_ERROR_01509 = 1509,
+    VALIDATION_ERROR_01510 = 1510,
+    VALIDATION_ERROR_01511 = 1511,
+    VALIDATION_ERROR_01512 = 1512,
+    VALIDATION_ERROR_01513 = 1513,
+    VALIDATION_ERROR_01514 = 1514,
+    VALIDATION_ERROR_01515 = 1515,
+    VALIDATION_ERROR_01516 = 1516,
+    VALIDATION_ERROR_01517 = 1517,
+    VALIDATION_ERROR_01518 = 1518,
+    VALIDATION_ERROR_01519 = 1519,
+    VALIDATION_ERROR_01520 = 1520,
+    VALIDATION_ERROR_01521 = 1521,
+    VALIDATION_ERROR_01522 = 1522,
+    VALIDATION_ERROR_01523 = 1523,
+    VALIDATION_ERROR_01524 = 1524,
+    VALIDATION_ERROR_01525 = 1525,
+    VALIDATION_ERROR_01526 = 1526,
+    VALIDATION_ERROR_01527 = 1527,
+    VALIDATION_ERROR_01528 = 1528,
+    VALIDATION_ERROR_01529 = 1529,
+    VALIDATION_ERROR_01530 = 1530,
+    VALIDATION_ERROR_01531 = 1531,
+    VALIDATION_ERROR_01532 = 1532,
+    VALIDATION_ERROR_01533 = 1533,
+    VALIDATION_ERROR_01534 = 1534,
+    VALIDATION_ERROR_01535 = 1535,
+    VALIDATION_ERROR_01536 = 1536,
+    VALIDATION_ERROR_01537 = 1537,
+    VALIDATION_ERROR_01538 = 1538,
+    VALIDATION_ERROR_01539 = 1539,
+    VALIDATION_ERROR_01540 = 1540,
+    VALIDATION_ERROR_01541 = 1541,
+    VALIDATION_ERROR_01542 = 1542,
+    VALIDATION_ERROR_01543 = 1543,
+    VALIDATION_ERROR_01544 = 1544,
+    VALIDATION_ERROR_01545 = 1545,
+    VALIDATION_ERROR_01546 = 1546,
+    VALIDATION_ERROR_01547 = 1547,
+    VALIDATION_ERROR_01548 = 1548,
+    VALIDATION_ERROR_01549 = 1549,
+    VALIDATION_ERROR_01550 = 1550,
+    VALIDATION_ERROR_01551 = 1551,
+    VALIDATION_ERROR_01552 = 1552,
+    VALIDATION_ERROR_01553 = 1553,
+    VALIDATION_ERROR_01554 = 1554,
+    VALIDATION_ERROR_01555 = 1555,
+    VALIDATION_ERROR_01556 = 1556,
+    VALIDATION_ERROR_01557 = 1557,
+    VALIDATION_ERROR_01558 = 1558,
+    VALIDATION_ERROR_01559 = 1559,
+    VALIDATION_ERROR_01560 = 1560,
+    VALIDATION_ERROR_01561 = 1561,
+    VALIDATION_ERROR_01562 = 1562,
+    VALIDATION_ERROR_01563 = 1563,
+    VALIDATION_ERROR_01564 = 1564,
+    VALIDATION_ERROR_01565 = 1565,
+    VALIDATION_ERROR_01566 = 1566,
+    VALIDATION_ERROR_01567 = 1567,
+    VALIDATION_ERROR_01568 = 1568,
+    VALIDATION_ERROR_01569 = 1569,
+    VALIDATION_ERROR_01570 = 1570,
+    VALIDATION_ERROR_01571 = 1571,
+    VALIDATION_ERROR_01572 = 1572,
+    VALIDATION_ERROR_01573 = 1573,
+    VALIDATION_ERROR_01600 = 1600,
+    VALIDATION_ERROR_01601 = 1601,
+    VALIDATION_ERROR_01602 = 1602,
+    VALIDATION_ERROR_01603 = 1603,
+    VALIDATION_ERROR_01604 = 1604,
+    VALIDATION_ERROR_01605 = 1605,
+    VALIDATION_ERROR_01606 = 1606,
+    VALIDATION_ERROR_01607 = 1607,
+    VALIDATION_ERROR_01608 = 1608,
+    VALIDATION_ERROR_01609 = 1609,
+    VALIDATION_ERROR_01610 = 1610,
+    VALIDATION_ERROR_01611 = 1611,
+    VALIDATION_ERROR_01612 = 1612,
+    VALIDATION_ERROR_01613 = 1613,
+    VALIDATION_ERROR_01614 = 1614,
+    VALIDATION_ERROR_01615 = 1615,
+    VALIDATION_ERROR_01616 = 1616,
+    VALIDATION_ERROR_01617 = 1617,
+    VALIDATION_ERROR_01618 = 1618,
+    VALIDATION_ERROR_01619 = 1619,
+    VALIDATION_ERROR_01620 = 1620,
+    VALIDATION_ERROR_01621 = 1621,
+    VALIDATION_ERROR_01622 = 1622,
+    VALIDATION_ERROR_01623 = 1623,
+    VALIDATION_ERROR_01624 = 1624,
+    VALIDATION_ERROR_01625 = 1625,
+    VALIDATION_ERROR_01626 = 1626,
+    VALIDATION_ERROR_01627 = 1627,
+    VALIDATION_ERROR_01628 = 1628,
+    VALIDATION_ERROR_01629 = 1629,
+    VALIDATION_ERROR_01630 = 1630,
+    VALIDATION_ERROR_01631 = 1631,
+    VALIDATION_ERROR_01632 = 1632,
+    VALIDATION_ERROR_01633 = 1633,
+    VALIDATION_ERROR_01634 = 1634,
+    VALIDATION_ERROR_01635 = 1635,
+    VALIDATION_ERROR_01636 = 1636,
+    VALIDATION_ERROR_01637 = 1637,
+    VALIDATION_ERROR_01638 = 1638,
+    VALIDATION_ERROR_01639 = 1639,
+    VALIDATION_ERROR_01640 = 1640,
+    VALIDATION_ERROR_01641 = 1641,
+    VALIDATION_ERROR_01642 = 1642,
+    VALIDATION_ERROR_01643 = 1643,
+    VALIDATION_ERROR_01644 = 1644,
+    VALIDATION_ERROR_01645 = 1645,
+    VALIDATION_ERROR_01646 = 1646,
+    VALIDATION_ERROR_01647 = 1647,
+    VALIDATION_ERROR_01648 = 1648,
+    VALIDATION_ERROR_01649 = 1649,
+    VALIDATION_ERROR_01650 = 1650,
+    VALIDATION_ERROR_01651 = 1651,
+    VALIDATION_ERROR_01652 = 1652,
+    VALIDATION_ERROR_01653 = 1653,
+    VALIDATION_ERROR_01654 = 1654,
+    VALIDATION_ERROR_01655 = 1655,
+    VALIDATION_ERROR_01656 = 1656,
+    VALIDATION_ERROR_01657 = 1657,
+    VALIDATION_ERROR_01658 = 1658,
+    VALIDATION_ERROR_01659 = 1659,
+    VALIDATION_ERROR_01660 = 1660,
+    VALIDATION_ERROR_01665 = 1665,
+    VALIDATION_ERROR_01666 = 1666,
+    VALIDATION_ERROR_01667 = 1667,
+    VALIDATION_ERROR_01668 = 1668,
+    VALIDATION_ERROR_01669 = 1669,
+    VALIDATION_ERROR_01670 = 1670,
+    VALIDATION_ERROR_01671 = 1671,
+    VALIDATION_ERROR_01672 = 1672,
+    VALIDATION_ERROR_01673 = 1673,
+    VALIDATION_ERROR_01674 = 1674,
+    VALIDATION_ERROR_01675 = 1675,
+    VALIDATION_ERROR_01676 = 1676,
+    VALIDATION_ERROR_01677 = 1677,
+    VALIDATION_ERROR_01679 = 1679,
+    VALIDATION_ERROR_01680 = 1680,
+    VALIDATION_ERROR_01683 = 1683,
+    VALIDATION_ERROR_01684 = 1684,
+    VALIDATION_ERROR_01685 = 1685,
+    VALIDATION_ERROR_01686 = 1686,
+    VALIDATION_ERROR_01687 = 1687,
+    VALIDATION_ERROR_01688 = 1688,
+    VALIDATION_ERROR_01689 = 1689,
+    VALIDATION_ERROR_01690 = 1690,
+    VALIDATION_ERROR_01691 = 1691,
+    VALIDATION_ERROR_01692 = 1692,
+    VALIDATION_ERROR_01693 = 1693,
+    VALIDATION_ERROR_01694 = 1694,
+    VALIDATION_ERROR_01695 = 1695,
+    VALIDATION_ERROR_01696 = 1696,
+    VALIDATION_ERROR_01697 = 1697,
+    VALIDATION_ERROR_01698 = 1698,
+    VALIDATION_ERROR_01699 = 1699,
+    VALIDATION_ERROR_01700 = 1700,
+    VALIDATION_ERROR_01701 = 1701,
+    VALIDATION_ERROR_01702 = 1702,
+    VALIDATION_ERROR_01703 = 1703,
+    VALIDATION_ERROR_01704 = 1704,
+    VALIDATION_ERROR_01705 = 1705,
+    VALIDATION_ERROR_01706 = 1706,
+    VALIDATION_ERROR_01707 = 1707,
+    VALIDATION_ERROR_01708 = 1708,
+    VALIDATION_ERROR_01709 = 1709,
+    VALIDATION_ERROR_01710 = 1710,
+    VALIDATION_ERROR_01711 = 1711,
+    VALIDATION_ERROR_01712 = 1712,
+    VALIDATION_ERROR_01713 = 1713,
+    VALIDATION_ERROR_01714 = 1714,
+    VALIDATION_ERROR_01715 = 1715,
+    VALIDATION_ERROR_01716 = 1716,
+    VALIDATION_ERROR_01717 = 1717,
+    VALIDATION_ERROR_01718 = 1718,
+    VALIDATION_ERROR_01719 = 1719,
+    VALIDATION_ERROR_01720 = 1720,
+    VALIDATION_ERROR_01721 = 1721,
+    VALIDATION_ERROR_01722 = 1722,
+    VALIDATION_ERROR_01723 = 1723,
+    VALIDATION_ERROR_01724 = 1724,
+    VALIDATION_ERROR_01725 = 1725,
+    VALIDATION_ERROR_01726 = 1726,
+    VALIDATION_ERROR_01727 = 1727,
+    VALIDATION_ERROR_01728 = 1728,
+    VALIDATION_ERROR_01729 = 1729,
+    VALIDATION_ERROR_01730 = 1730,
+    VALIDATION_ERROR_01731 = 1731,
+    VALIDATION_ERROR_01732 = 1732,
+    VALIDATION_ERROR_01733 = 1733,
+    VALIDATION_ERROR_01734 = 1734,
+    VALIDATION_ERROR_01735 = 1735,
+    VALIDATION_ERROR_01736 = 1736,
+    VALIDATION_ERROR_01737 = 1737,
+    VALIDATION_ERROR_01738 = 1738,
+    VALIDATION_ERROR_01739 = 1739,
+    VALIDATION_ERROR_01740 = 1740,
+    VALIDATION_ERROR_01741 = 1741,
+    VALIDATION_ERROR_01742 = 1742,
+    VALIDATION_ERROR_01743 = 1743,
+    VALIDATION_ERROR_01744 = 1744,
+    VALIDATION_ERROR_01745 = 1745,
+    VALIDATION_ERROR_01746 = 1746,
+    VALIDATION_ERROR_01747 = 1747,
+    VALIDATION_ERROR_01748 = 1748,
+    VALIDATION_ERROR_01749 = 1749,
+    VALIDATION_ERROR_01750 = 1750,
+    VALIDATION_ERROR_01751 = 1751,
+    VALIDATION_ERROR_01752 = 1752,
+    VALIDATION_ERROR_01753 = 1753,
+    VALIDATION_ERROR_01754 = 1754,
+    VALIDATION_ERROR_01755 = 1755,
+    VALIDATION_ERROR_01756 = 1756,
+    VALIDATION_ERROR_01757 = 1757,
+    VALIDATION_ERROR_01758 = 1758,
+    VALIDATION_ERROR_01759 = 1759,
+    VALIDATION_ERROR_01760 = 1760,
+    VALIDATION_ERROR_01761 = 1761,
+    VALIDATION_ERROR_01762 = 1762,
+    VALIDATION_ERROR_01763 = 1763,
+    VALIDATION_ERROR_01764 = 1764,
+    VALIDATION_ERROR_01765 = 1765,
+    VALIDATION_ERROR_01766 = 1766,
+    VALIDATION_ERROR_01767 = 1767,
+    VALIDATION_ERROR_01768 = 1768,
+    VALIDATION_ERROR_01769 = 1769,
+    VALIDATION_ERROR_01770 = 1770,
+    VALIDATION_ERROR_01771 = 1771,
+    VALIDATION_ERROR_01772 = 1772,
+    VALIDATION_ERROR_01773 = 1773,
+    VALIDATION_ERROR_01774 = 1774,
+    VALIDATION_ERROR_01775 = 1775,
+    VALIDATION_ERROR_01776 = 1776,
+    VALIDATION_ERROR_01777 = 1777,
+    VALIDATION_ERROR_01778 = 1778,
+    VALIDATION_ERROR_01779 = 1779,
+    VALIDATION_ERROR_01780 = 1780,
+    VALIDATION_ERROR_01781 = 1781,
+    VALIDATION_ERROR_01782 = 1782,
+    VALIDATION_ERROR_01783 = 1783,
+    VALIDATION_ERROR_01784 = 1784,
+    VALIDATION_ERROR_01785 = 1785,
+    VALIDATION_ERROR_01786 = 1786,
+    VALIDATION_ERROR_01787 = 1787,
+    VALIDATION_ERROR_01788 = 1788,
+    VALIDATION_ERROR_01789 = 1789,
+    VALIDATION_ERROR_01790 = 1790,
+    VALIDATION_ERROR_01791 = 1791,
+    VALIDATION_ERROR_01792 = 1792,
+    VALIDATION_ERROR_01793 = 1793,
+    VALIDATION_ERROR_01794 = 1794,
+    VALIDATION_ERROR_01795 = 1795,
+    VALIDATION_ERROR_01796 = 1796,
+    VALIDATION_ERROR_01797 = 1797,
+    VALIDATION_ERROR_01798 = 1798,
+    VALIDATION_ERROR_01799 = 1799,
+    VALIDATION_ERROR_01800 = 1800,
+    VALIDATION_ERROR_01801 = 1801,
+    VALIDATION_ERROR_01802 = 1802,
+    VALIDATION_ERROR_01803 = 1803,
+    VALIDATION_ERROR_01804 = 1804,
+    VALIDATION_ERROR_01805 = 1805,
+    VALIDATION_ERROR_01806 = 1806,
+    VALIDATION_ERROR_01807 = 1807,
+    VALIDATION_ERROR_01808 = 1808,
+    VALIDATION_ERROR_01809 = 1809,
+    VALIDATION_ERROR_01810 = 1810,
+    VALIDATION_ERROR_01811 = 1811,
+    VALIDATION_ERROR_01812 = 1812,
+    VALIDATION_ERROR_01813 = 1813,
+    VALIDATION_ERROR_01814 = 1814,
+    VALIDATION_ERROR_01815 = 1815,
+    VALIDATION_ERROR_01816 = 1816,
+    VALIDATION_ERROR_01817 = 1817,
+    VALIDATION_ERROR_01818 = 1818,
+    VALIDATION_ERROR_01819 = 1819,
+    VALIDATION_ERROR_01820 = 1820,
+    VALIDATION_ERROR_01821 = 1821,
+    VALIDATION_ERROR_01822 = 1822,
+    VALIDATION_ERROR_01823 = 1823,
+    VALIDATION_ERROR_01824 = 1824,
+    VALIDATION_ERROR_01825 = 1825,
+    VALIDATION_ERROR_01826 = 1826,
+    VALIDATION_ERROR_01827 = 1827,
+    VALIDATION_ERROR_01828 = 1828,
+    VALIDATION_ERROR_01829 = 1829,
+    VALIDATION_ERROR_01830 = 1830,
+    VALIDATION_ERROR_01831 = 1831,
+    VALIDATION_ERROR_01832 = 1832,
+    VALIDATION_ERROR_01833 = 1833,
+    VALIDATION_ERROR_01834 = 1834,
+    VALIDATION_ERROR_01836 = 1836,
+    VALIDATION_ERROR_01837 = 1837,
+    VALIDATION_ERROR_01838 = 1838,
+    VALIDATION_ERROR_01839 = 1839,
+    VALIDATION_ERROR_01840 = 1840,
+    VALIDATION_ERROR_01841 = 1841,
+    VALIDATION_ERROR_01842 = 1842,
+    VALIDATION_ERROR_01843 = 1843,
+    VALIDATION_ERROR_01844 = 1844,
+    VALIDATION_ERROR_01845 = 1845,
+    VALIDATION_ERROR_01846 = 1846,
+    VALIDATION_ERROR_01847 = 1847,
+    VALIDATION_ERROR_01848 = 1848,
+    VALIDATION_ERROR_01849 = 1849,
+    VALIDATION_ERROR_01850 = 1850,
+    VALIDATION_ERROR_01851 = 1851,
+    VALIDATION_ERROR_01852 = 1852,
+    VALIDATION_ERROR_01853 = 1853,
+    VALIDATION_ERROR_01854 = 1854,
+    VALIDATION_ERROR_01855 = 1855,
+    VALIDATION_ERROR_01856 = 1856,
+    VALIDATION_ERROR_01857 = 1857,
+    VALIDATION_ERROR_01858 = 1858,
+    VALIDATION_ERROR_01859 = 1859,
+    VALIDATION_ERROR_01860 = 1860,
+    VALIDATION_ERROR_01861 = 1861,
+    VALIDATION_ERROR_01862 = 1862,
+    VALIDATION_ERROR_01863 = 1863,
+    VALIDATION_ERROR_01864 = 1864,
+    VALIDATION_ERROR_01865 = 1865,
+    VALIDATION_ERROR_01866 = 1866,
+    VALIDATION_ERROR_01867 = 1867,
+    VALIDATION_ERROR_01868 = 1868,
+    VALIDATION_ERROR_01869 = 1869,
+    VALIDATION_ERROR_01870 = 1870,
+    VALIDATION_ERROR_01871 = 1871,
+    VALIDATION_ERROR_01872 = 1872,
+    VALIDATION_ERROR_01873 = 1873,
+    VALIDATION_ERROR_01874 = 1874,
+    VALIDATION_ERROR_01875 = 1875,
+    VALIDATION_ERROR_01876 = 1876,
+    VALIDATION_ERROR_01877 = 1877,
+    VALIDATION_ERROR_01878 = 1878,
+    VALIDATION_ERROR_01879 = 1879,
+    VALIDATION_ERROR_01880 = 1880,
+    VALIDATION_ERROR_01881 = 1881,
+    VALIDATION_ERROR_01882 = 1882,
+    VALIDATION_ERROR_01883 = 1883,
+    VALIDATION_ERROR_01884 = 1884,
+    VALIDATION_ERROR_01885 = 1885,
+    VALIDATION_ERROR_01886 = 1886,
+    VALIDATION_ERROR_01887 = 1887,
+    VALIDATION_ERROR_01888 = 1888,
+    VALIDATION_ERROR_01889 = 1889,
+    VALIDATION_ERROR_01890 = 1890,
+    VALIDATION_ERROR_01891 = 1891,
+    VALIDATION_ERROR_01892 = 1892,
+    VALIDATION_ERROR_01893 = 1893,
+    VALIDATION_ERROR_01894 = 1894,
+    VALIDATION_ERROR_01895 = 1895,
+    VALIDATION_ERROR_01896 = 1896,
+    VALIDATION_ERROR_01897 = 1897,
+    VALIDATION_ERROR_01898 = 1898,
+    VALIDATION_ERROR_01899 = 1899,
+    VALIDATION_ERROR_01900 = 1900,
+    VALIDATION_ERROR_01901 = 1901,
+    VALIDATION_ERROR_01902 = 1902,
+    VALIDATION_ERROR_01903 = 1903,
+    VALIDATION_ERROR_01904 = 1904,
+    VALIDATION_ERROR_01905 = 1905,
+    VALIDATION_ERROR_01906 = 1906,
+    VALIDATION_ERROR_01907 = 1907,
+    VALIDATION_ERROR_01908 = 1908,
+    VALIDATION_ERROR_01909 = 1909,
+    VALIDATION_ERROR_01910 = 1910,
+    VALIDATION_ERROR_01911 = 1911,
+    VALIDATION_ERROR_01912 = 1912,
+    VALIDATION_ERROR_01913 = 1913,
+    VALIDATION_ERROR_01914 = 1914,
+    VALIDATION_ERROR_01915 = 1915,
+    VALIDATION_ERROR_01916 = 1916,
+    VALIDATION_ERROR_01917 = 1917,
+    VALIDATION_ERROR_01918 = 1918,
+    VALIDATION_ERROR_01919 = 1919,
+    VALIDATION_ERROR_01920 = 1920,
+    VALIDATION_ERROR_01921 = 1921,
+    VALIDATION_ERROR_01922 = 1922,
+    VALIDATION_ERROR_01923 = 1923,
+    VALIDATION_ERROR_01924 = 1924,
+    VALIDATION_ERROR_01925 = 1925,
+    VALIDATION_ERROR_01926 = 1926,
+    VALIDATION_ERROR_01927 = 1927,
+    VALIDATION_ERROR_01928 = 1928,
+    VALIDATION_ERROR_01929 = 1929,
+    VALIDATION_ERROR_01930 = 1930,
+    VALIDATION_ERROR_01931 = 1931,
+    VALIDATION_ERROR_01932 = 1932,
+    VALIDATION_ERROR_01933 = 1933,
+    VALIDATION_ERROR_01934 = 1934,
+    VALIDATION_ERROR_01935 = 1935,
+    VALIDATION_ERROR_01936 = 1936,
+    VALIDATION_ERROR_01937 = 1937,
+    VALIDATION_ERROR_01938 = 1938,
+    VALIDATION_ERROR_01939 = 1939,
+    VALIDATION_ERROR_01940 = 1940,
+    VALIDATION_ERROR_01941 = 1941,
+    VALIDATION_ERROR_01942 = 1942,
+    VALIDATION_ERROR_01943 = 1943,
+    VALIDATION_ERROR_01944 = 1944,
+    VALIDATION_ERROR_01945 = 1945,
+    VALIDATION_ERROR_01946 = 1946,
+    VALIDATION_ERROR_01947 = 1947,
+    VALIDATION_ERROR_01948 = 1948,
+    VALIDATION_ERROR_01949 = 1949,
+    VALIDATION_ERROR_01950 = 1950,
+    VALIDATION_ERROR_01951 = 1951,
+    VALIDATION_ERROR_01952 = 1952,
+    VALIDATION_ERROR_01953 = 1953,
+    VALIDATION_ERROR_01954 = 1954,
+    VALIDATION_ERROR_01955 = 1955,
+    VALIDATION_ERROR_01956 = 1956,
+    VALIDATION_ERROR_01957 = 1957,
+    VALIDATION_ERROR_01958 = 1958,
+    VALIDATION_ERROR_01959 = 1959,
+    VALIDATION_ERROR_01960 = 1960,
+    VALIDATION_ERROR_01961 = 1961,
+    VALIDATION_ERROR_01962 = 1962,
+    VALIDATION_ERROR_01963 = 1963,
+    VALIDATION_ERROR_01964 = 1964,
+    VALIDATION_ERROR_01965 = 1965,
+    VALIDATION_ERROR_01966 = 1966,
+    VALIDATION_ERROR_01967 = 1967,
+    VALIDATION_ERROR_01968 = 1968,
+    VALIDATION_ERROR_01969 = 1969,
+    VALIDATION_ERROR_01970 = 1970,
+    VALIDATION_ERROR_01971 = 1971,
+    VALIDATION_ERROR_01972 = 1972,
+    VALIDATION_ERROR_01973 = 1973,
+    VALIDATION_ERROR_01974 = 1974,
+    VALIDATION_ERROR_01975 = 1975,
+    VALIDATION_ERROR_01976 = 1976,
+    VALIDATION_ERROR_01977 = 1977,
+    VALIDATION_ERROR_01978 = 1978,
+    VALIDATION_ERROR_01979 = 1979,
+    VALIDATION_ERROR_01980 = 1980,
+    VALIDATION_ERROR_01981 = 1981,
+    VALIDATION_ERROR_01982 = 1982,
+    VALIDATION_ERROR_01983 = 1983,
+    VALIDATION_ERROR_01984 = 1984,
+    VALIDATION_ERROR_01985 = 1985,
+    VALIDATION_ERROR_01986 = 1986,
+    VALIDATION_ERROR_01987 = 1987,
+    VALIDATION_ERROR_01988 = 1988,
+    VALIDATION_ERROR_01989 = 1989,
+    VALIDATION_ERROR_01990 = 1990,
+    VALIDATION_ERROR_01991 = 1991,
+    VALIDATION_ERROR_01992 = 1992,
+    VALIDATION_ERROR_01993 = 1993,
+    VALIDATION_ERROR_01994 = 1994,
+    VALIDATION_ERROR_01995 = 1995,
+    VALIDATION_ERROR_01996 = 1996,
+    VALIDATION_ERROR_01997 = 1997,
+    VALIDATION_ERROR_01998 = 1998,
+    VALIDATION_ERROR_01999 = 1999,
+    VALIDATION_ERROR_02000 = 2000,
+    VALIDATION_ERROR_02001 = 2001,
+    VALIDATION_ERROR_02002 = 2002,
+    VALIDATION_ERROR_02003 = 2003,
+    VALIDATION_ERROR_02004 = 2004,
+    VALIDATION_ERROR_02005 = 2005,
+    VALIDATION_ERROR_02006 = 2006,
+    VALIDATION_ERROR_02007 = 2007,
+    VALIDATION_ERROR_02008 = 2008,
+    VALIDATION_ERROR_02009 = 2009,
+    VALIDATION_ERROR_02010 = 2010,
+    VALIDATION_ERROR_02011 = 2011,
+    VALIDATION_ERROR_02012 = 2012,
+    VALIDATION_ERROR_02013 = 2013,
+    VALIDATION_ERROR_02014 = 2014,
+    VALIDATION_ERROR_02015 = 2015,
+    VALIDATION_ERROR_02016 = 2016,
+    VALIDATION_ERROR_02017 = 2017,
+    VALIDATION_ERROR_02018 = 2018,
+    VALIDATION_ERROR_02019 = 2019,
+    VALIDATION_ERROR_02020 = 2020,
+    VALIDATION_ERROR_02021 = 2021,
+    VALIDATION_ERROR_02022 = 2022,
+    VALIDATION_ERROR_02023 = 2023,
+    VALIDATION_ERROR_02024 = 2024,
+    VALIDATION_ERROR_02025 = 2025,
+    VALIDATION_ERROR_02026 = 2026,
+    VALIDATION_ERROR_02027 = 2027,
+    VALIDATION_ERROR_02028 = 2028,
+    VALIDATION_ERROR_02029 = 2029,
+    VALIDATION_ERROR_02030 = 2030,
+    VALIDATION_ERROR_02031 = 2031,
+    VALIDATION_ERROR_02032 = 2032,
+    VALIDATION_ERROR_02033 = 2033,
+    VALIDATION_ERROR_02034 = 2034,
+    VALIDATION_ERROR_02035 = 2035,
+    VALIDATION_ERROR_02036 = 2036,
+    VALIDATION_ERROR_02040 = 2040,
+    VALIDATION_ERROR_02041 = 2041,
+    VALIDATION_ERROR_02042 = 2042,
+    VALIDATION_ERROR_02043 = 2043,
+    VALIDATION_ERROR_02044 = 2044,
+    VALIDATION_ERROR_02045 = 2045,
+    VALIDATION_ERROR_02046 = 2046,
+    VALIDATION_ERROR_02047 = 2047,
+    VALIDATION_ERROR_02048 = 2048,
+    VALIDATION_ERROR_02049 = 2049,
+    VALIDATION_ERROR_02050 = 2050,
+    VALIDATION_ERROR_02051 = 2051,
+    VALIDATION_ERROR_02052 = 2052,
+    VALIDATION_ERROR_02053 = 2053,
+    VALIDATION_ERROR_02054 = 2054,
+    VALIDATION_ERROR_02055 = 2055,
+    VALIDATION_ERROR_02056 = 2056,
+    VALIDATION_ERROR_02057 = 2057,
+    VALIDATION_ERROR_02058 = 2058,
+    VALIDATION_ERROR_02059 = 2059,
+    VALIDATION_ERROR_02060 = 2060,
+    VALIDATION_ERROR_02061 = 2061,
+    VALIDATION_ERROR_02062 = 2062,
+    VALIDATION_ERROR_02063 = 2063,
+    VALIDATION_ERROR_02064 = 2064,
+    VALIDATION_ERROR_02065 = 2065,
+    VALIDATION_ERROR_02066 = 2066,
+    VALIDATION_ERROR_02067 = 2067,
+    VALIDATION_ERROR_02068 = 2068,
+    VALIDATION_ERROR_02069 = 2069,
+    VALIDATION_ERROR_02070 = 2070,
+    VALIDATION_ERROR_02071 = 2071,
+    VALIDATION_ERROR_02072 = 2072,
+    VALIDATION_ERROR_02073 = 2073,
+    VALIDATION_ERROR_02074 = 2074,
+    VALIDATION_ERROR_02075 = 2075,
+    VALIDATION_ERROR_02076 = 2076,
+    VALIDATION_ERROR_02077 = 2077,
+    VALIDATION_ERROR_02078 = 2078,
+    VALIDATION_ERROR_02079 = 2079,
+    VALIDATION_ERROR_02080 = 2080,
+    VALIDATION_ERROR_02081 = 2081,
+    VALIDATION_ERROR_02082 = 2082,
+    VALIDATION_ERROR_02083 = 2083,
+    VALIDATION_ERROR_02084 = 2084,
+    VALIDATION_ERROR_02085 = 2085,
+    VALIDATION_ERROR_02086 = 2086,
+    VALIDATION_ERROR_02087 = 2087,
+    VALIDATION_ERROR_02088 = 2088,
+    VALIDATION_ERROR_02089 = 2089,
+    VALIDATION_ERROR_02090 = 2090,
+    VALIDATION_ERROR_02091 = 2091,
+    VALIDATION_ERROR_02092 = 2092,
+    VALIDATION_ERROR_02093 = 2093,
+    VALIDATION_ERROR_02094 = 2094,
+    VALIDATION_ERROR_02095 = 2095,
+    VALIDATION_ERROR_02096 = 2096,
+    VALIDATION_ERROR_02097 = 2097,
+    VALIDATION_ERROR_02098 = 2098,
+    VALIDATION_ERROR_02099 = 2099,
+    VALIDATION_ERROR_02100 = 2100,
+    VALIDATION_ERROR_02101 = 2101,
+    VALIDATION_ERROR_02102 = 2102,
+    VALIDATION_ERROR_02103 = 2103,
+    VALIDATION_ERROR_02104 = 2104,
+    VALIDATION_ERROR_02105 = 2105,
+    VALIDATION_ERROR_02106 = 2106,
+    VALIDATION_ERROR_02107 = 2107,
+    VALIDATION_ERROR_02108 = 2108,
+    VALIDATION_ERROR_02109 = 2109,
+    VALIDATION_ERROR_02110 = 2110,
+    VALIDATION_ERROR_02111 = 2111,
+    VALIDATION_ERROR_02112 = 2112,
+    VALIDATION_ERROR_02113 = 2113,
+    VALIDATION_ERROR_02114 = 2114,
+    VALIDATION_ERROR_02115 = 2115,
+    VALIDATION_ERROR_02116 = 2116,
+    VALIDATION_ERROR_02117 = 2117,
+    VALIDATION_ERROR_02118 = 2118,
+    VALIDATION_ERROR_02119 = 2119,
+    VALIDATION_ERROR_02120 = 2120,
+    VALIDATION_ERROR_02121 = 2121,
+    VALIDATION_ERROR_02122 = 2122,
+    VALIDATION_ERROR_02123 = 2123,
+    VALIDATION_ERROR_02124 = 2124,
+    VALIDATION_ERROR_02125 = 2125,
+    VALIDATION_ERROR_02126 = 2126,
+    VALIDATION_ERROR_02127 = 2127,
+    VALIDATION_ERROR_02128 = 2128,
+    VALIDATION_ERROR_02129 = 2129,
+    VALIDATION_ERROR_02130 = 2130,
+    VALIDATION_ERROR_02131 = 2131,
+    VALIDATION_ERROR_02132 = 2132,
+    VALIDATION_ERROR_02133 = 2133,
+    VALIDATION_ERROR_02134 = 2134,
+    VALIDATION_ERROR_02135 = 2135,
+    VALIDATION_ERROR_02136 = 2136,
+    VALIDATION_ERROR_02137 = 2137,
+    VALIDATION_ERROR_02138 = 2138,
+    VALIDATION_ERROR_02139 = 2139,
+    VALIDATION_ERROR_02140 = 2140,
+    VALIDATION_ERROR_02141 = 2141,
+    VALIDATION_ERROR_02142 = 2142,
+    VALIDATION_ERROR_02143 = 2143,
+    VALIDATION_ERROR_02144 = 2144,
+    VALIDATION_ERROR_02145 = 2145,
+    VALIDATION_ERROR_02146 = 2146,
+    VALIDATION_ERROR_02147 = 2147,
+    VALIDATION_ERROR_02148 = 2148,
+    VALIDATION_ERROR_02149 = 2149,
+    VALIDATION_ERROR_02150 = 2150,
+    VALIDATION_ERROR_02151 = 2151,
+    VALIDATION_ERROR_02152 = 2152,
+    VALIDATION_ERROR_02153 = 2153,
+    VALIDATION_ERROR_02154 = 2154,
+    VALIDATION_ERROR_02155 = 2155,
+    VALIDATION_ERROR_02156 = 2156,
+    VALIDATION_ERROR_02157 = 2157,
+    VALIDATION_ERROR_02158 = 2158,
+    VALIDATION_ERROR_02159 = 2159,
+    VALIDATION_ERROR_02160 = 2160,
+    VALIDATION_ERROR_02161 = 2161,
+    VALIDATION_ERROR_02162 = 2162,
+    VALIDATION_ERROR_02163 = 2163,
+    VALIDATION_ERROR_02164 = 2164,
+    VALIDATION_ERROR_02165 = 2165,
+    VALIDATION_ERROR_02166 = 2166,
+    VALIDATION_ERROR_02167 = 2167,
+    VALIDATION_ERROR_02168 = 2168,
+    VALIDATION_ERROR_02169 = 2169,
+    VALIDATION_ERROR_02170 = 2170,
+    VALIDATION_ERROR_02171 = 2171,
+    VALIDATION_ERROR_02172 = 2172,
+    VALIDATION_ERROR_02173 = 2173,
+    VALIDATION_ERROR_02174 = 2174,
+    VALIDATION_ERROR_02175 = 2175,
+    VALIDATION_ERROR_02176 = 2176,
+    VALIDATION_ERROR_02177 = 2177,
+    VALIDATION_ERROR_02178 = 2178,
+    VALIDATION_ERROR_02179 = 2179,
+    VALIDATION_ERROR_02180 = 2180,
+    VALIDATION_ERROR_02181 = 2181,
+    VALIDATION_ERROR_02182 = 2182,
+    VALIDATION_ERROR_02183 = 2183,
+    VALIDATION_ERROR_02184 = 2184,
+    VALIDATION_ERROR_02185 = 2185,
+    VALIDATION_ERROR_02186 = 2186,
+    VALIDATION_ERROR_02187 = 2187,
+    VALIDATION_ERROR_02188 = 2188,
+    VALIDATION_ERROR_02189 = 2189,
+    VALIDATION_ERROR_02190 = 2190,
+    VALIDATION_ERROR_02191 = 2191,
+    VALIDATION_ERROR_02192 = 2192,
+    VALIDATION_ERROR_02193 = 2193,
+    VALIDATION_ERROR_02194 = 2194,
+    VALIDATION_ERROR_02195 = 2195,
+    VALIDATION_ERROR_02196 = 2196,
+    VALIDATION_ERROR_02197 = 2197,
+    VALIDATION_ERROR_02198 = 2198,
+    VALIDATION_ERROR_02199 = 2199,
+    VALIDATION_ERROR_02200 = 2200,
+    VALIDATION_ERROR_02201 = 2201,
+    VALIDATION_ERROR_02202 = 2202,
+    VALIDATION_ERROR_02203 = 2203,
+    VALIDATION_ERROR_02204 = 2204,
+    VALIDATION_ERROR_02205 = 2205,
+    VALIDATION_ERROR_02206 = 2206,
+    VALIDATION_ERROR_02207 = 2207,
+    VALIDATION_ERROR_02208 = 2208,
+    VALIDATION_ERROR_02209 = 2209,
+    VALIDATION_ERROR_02210 = 2210,
+    VALIDATION_ERROR_02211 = 2211,
+    VALIDATION_ERROR_02212 = 2212,
+    VALIDATION_ERROR_02213 = 2213,
+    VALIDATION_ERROR_02214 = 2214,
+    VALIDATION_ERROR_02215 = 2215,
+    VALIDATION_ERROR_02216 = 2216,
+    VALIDATION_ERROR_02217 = 2217,
+    VALIDATION_ERROR_02218 = 2218,
+    VALIDATION_ERROR_02219 = 2219,
+    VALIDATION_ERROR_02220 = 2220,
+    VALIDATION_ERROR_02221 = 2221,
+    VALIDATION_ERROR_02222 = 2222,
+    VALIDATION_ERROR_02223 = 2223,
+    VALIDATION_ERROR_02224 = 2224,
+    VALIDATION_ERROR_02225 = 2225,
+    VALIDATION_ERROR_02226 = 2226,
+    VALIDATION_ERROR_02227 = 2227,
+    VALIDATION_ERROR_02228 = 2228,
+    VALIDATION_ERROR_02229 = 2229,
+    VALIDATION_ERROR_02230 = 2230,
+    VALIDATION_ERROR_02231 = 2231,
+    VALIDATION_ERROR_02232 = 2232,
+    VALIDATION_ERROR_02233 = 2233,
+    VALIDATION_ERROR_02234 = 2234,
+    VALIDATION_ERROR_02235 = 2235,
+    VALIDATION_ERROR_02236 = 2236,
+    VALIDATION_ERROR_02237 = 2237,
+    VALIDATION_ERROR_02238 = 2238,
+    VALIDATION_ERROR_02239 = 2239,
+    VALIDATION_ERROR_02240 = 2240,
+    VALIDATION_ERROR_02241 = 2241,
+    VALIDATION_ERROR_02242 = 2242,
+    VALIDATION_ERROR_02243 = 2243,
+    VALIDATION_ERROR_02244 = 2244,
+    VALIDATION_ERROR_02245 = 2245,
+    VALIDATION_ERROR_02246 = 2246,
+    VALIDATION_ERROR_02247 = 2247,
+    VALIDATION_ERROR_02248 = 2248,
+    VALIDATION_ERROR_02249 = 2249,
+    VALIDATION_ERROR_02250 = 2250,
+    VALIDATION_ERROR_02251 = 2251,
+    VALIDATION_ERROR_02252 = 2252,
+    VALIDATION_ERROR_02253 = 2253,
+    VALIDATION_ERROR_02254 = 2254,
+    VALIDATION_ERROR_02255 = 2255,
+    VALIDATION_ERROR_02256 = 2256,
+    VALIDATION_ERROR_02257 = 2257,
+    VALIDATION_ERROR_02258 = 2258,
+    VALIDATION_ERROR_02259 = 2259,
+    VALIDATION_ERROR_02260 = 2260,
+    VALIDATION_ERROR_02261 = 2261,
+    VALIDATION_ERROR_02262 = 2262,
+    VALIDATION_ERROR_02263 = 2263,
+    VALIDATION_ERROR_02264 = 2264,
+    VALIDATION_ERROR_02265 = 2265,
+    VALIDATION_ERROR_02266 = 2266,
+    VALIDATION_ERROR_02267 = 2267,
+    VALIDATION_ERROR_02268 = 2268,
+    VALIDATION_ERROR_02269 = 2269,
+    VALIDATION_ERROR_02270 = 2270,
+    VALIDATION_ERROR_02271 = 2271,
+    VALIDATION_ERROR_02272 = 2272,
+    VALIDATION_ERROR_02273 = 2273,
+    VALIDATION_ERROR_02274 = 2274,
+    VALIDATION_ERROR_02275 = 2275,
+    VALIDATION_ERROR_02276 = 2276,
+    VALIDATION_ERROR_02277 = 2277,
+    VALIDATION_ERROR_02278 = 2278,
+    VALIDATION_ERROR_02279 = 2279,
+    VALIDATION_ERROR_02280 = 2280,
+    VALIDATION_ERROR_02281 = 2281,
+    VALIDATION_ERROR_02282 = 2282,
+    VALIDATION_ERROR_02283 = 2283,
+    VALIDATION_ERROR_02284 = 2284,
+    VALIDATION_ERROR_02285 = 2285,
+    VALIDATION_ERROR_02286 = 2286,
+    VALIDATION_ERROR_02287 = 2287,
+    VALIDATION_ERROR_02288 = 2288,
+    VALIDATION_ERROR_02289 = 2289,
+    VALIDATION_ERROR_02290 = 2290,
+    VALIDATION_ERROR_02291 = 2291,
+    VALIDATION_ERROR_02292 = 2292,
+    VALIDATION_ERROR_02293 = 2293,
+    VALIDATION_ERROR_02294 = 2294,
+    VALIDATION_ERROR_02295 = 2295,
+    VALIDATION_ERROR_02296 = 2296,
+    VALIDATION_ERROR_02297 = 2297,
+    VALIDATION_ERROR_02298 = 2298,
+    VALIDATION_ERROR_02299 = 2299,
+    VALIDATION_ERROR_02300 = 2300,
+    VALIDATION_ERROR_02301 = 2301,
+    VALIDATION_ERROR_02302 = 2302,
+    VALIDATION_ERROR_02303 = 2303,
+    VALIDATION_ERROR_02304 = 2304,
+    VALIDATION_ERROR_02305 = 2305,
+    VALIDATION_ERROR_02306 = 2306,
+    VALIDATION_ERROR_02307 = 2307,
+    VALIDATION_ERROR_02308 = 2308,
+    VALIDATION_ERROR_02309 = 2309,
+    VALIDATION_ERROR_02310 = 2310,
+    VALIDATION_ERROR_02311 = 2311,
+    VALIDATION_ERROR_02312 = 2312,
+    VALIDATION_ERROR_02313 = 2313,
+    VALIDATION_ERROR_02314 = 2314,
+    VALIDATION_ERROR_02315 = 2315,
+    VALIDATION_ERROR_02316 = 2316,
+    VALIDATION_ERROR_02317 = 2317,
+    VALIDATION_ERROR_02318 = 2318,
+    VALIDATION_ERROR_02319 = 2319,
+    VALIDATION_ERROR_02320 = 2320,
+    VALIDATION_ERROR_02321 = 2321,
+    VALIDATION_ERROR_02322 = 2322,
+    VALIDATION_ERROR_02323 = 2323,
+    VALIDATION_ERROR_02324 = 2324,
+    VALIDATION_ERROR_02325 = 2325,
+    VALIDATION_ERROR_02326 = 2326,
+    VALIDATION_ERROR_02327 = 2327,
+    VALIDATION_ERROR_02328 = 2328,
+    VALIDATION_ERROR_02329 = 2329,
+    VALIDATION_ERROR_02330 = 2330,
+    VALIDATION_ERROR_02331 = 2331,
+    VALIDATION_ERROR_02332 = 2332,
+    VALIDATION_ERROR_02333 = 2333,
+    VALIDATION_ERROR_02334 = 2334,
+    VALIDATION_ERROR_02335 = 2335,
+    VALIDATION_ERROR_02336 = 2336,
+    VALIDATION_ERROR_02337 = 2337,
+    VALIDATION_ERROR_02338 = 2338,
+    VALIDATION_ERROR_02339 = 2339,
+    VALIDATION_ERROR_02340 = 2340,
+    VALIDATION_ERROR_02341 = 2341,
+    VALIDATION_ERROR_02342 = 2342,
+    VALIDATION_ERROR_02343 = 2343,
+    VALIDATION_ERROR_02344 = 2344,
+    VALIDATION_ERROR_02345 = 2345,
+    VALIDATION_ERROR_MAX_ENUM = 2346,
+};
+
+// Mapping from unique validation error enum to the corresponding error message
+// The error message should be appended to the end of a custom error message that is passed
+// as the pMessage parameter to the PFN_vkDebugReportCallbackEXT function
+static std::unordered_map<int, char const *const> validation_error_map{
+    {VALIDATION_ERROR_00000, "For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'If instance is not NULL, instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.8)"},
+    {VALIDATION_ERROR_00001, "For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.8)"},
+    {VALIDATION_ERROR_00002, "For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.15)"},
+    {VALIDATION_ERROR_00003, "For more information refer to Vulkan Spec Section '3.1. Command Function Pointers' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.5.3.15)"},
+    {VALIDATION_ERROR_00004, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pCreateInfo must be a pointer to a valid VkInstanceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)"},
+    {VALIDATION_ERROR_00005, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)"},
+    {VALIDATION_ERROR_00006, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pInstance must be a pointer to a VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateInstance)"},
+    {VALIDATION_ERROR_00007, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'sType must be VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00008, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00009, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00010, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pApplicationInfo is not NULL, pApplicationInfo must be a pointer to a valid VkApplicationInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00011, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If enabledLayerCount is not 0, ppEnabledLayerNames must be a pointer to an array of enabledLayerCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00012, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If enabledExtensionCount is not 0, ppEnabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkInstanceCreateInfo)"},
+    {VALIDATION_ERROR_00013, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'apiVersion must be zero, or otherwise it must be a version that the implementation supports, or supports an effective substitute for' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)"},
+    {VALIDATION_ERROR_00014, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'sType must be VK_STRUCTURE_TYPE_APPLICATION_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)"},
+    {VALIDATION_ERROR_00015, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)"},
+    {VALIDATION_ERROR_00016, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pApplicationName is not NULL, pApplicationName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)"},
+    {VALIDATION_ERROR_00017, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pEngineName is not NULL, pEngineName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkApplicationInfo)"},
+    {VALIDATION_ERROR_00018, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'All child objects created using instance must have been destroyed prior to destroying instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)"},
+    {VALIDATION_ERROR_00019, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)"},
+    {VALIDATION_ERROR_00020, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)"},
+    {VALIDATION_ERROR_00021, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If instance is not NULL, instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)"},
+    {VALIDATION_ERROR_00022, "For more information refer to Vulkan Spec Section '3.2. Instances' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyInstance)"},
+    {VALIDATION_ERROR_00023, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)"},
+    {VALIDATION_ERROR_00024, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pPhysicalDeviceCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)"},
+    {VALIDATION_ERROR_00025, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'If the value referenced by pPhysicalDeviceCount is not 0, and pPhysicalDevices is not NULL, pPhysicalDevices must be a pointer to an array of pPhysicalDeviceCount VkPhysicalDevice handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumeratePhysicalDevices)"},
+    {VALIDATION_ERROR_00026, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceProperties)"},
+    {VALIDATION_ERROR_00027, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pProperties must be a pointer to a VkPhysicalDeviceProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceProperties)"},
+    {VALIDATION_ERROR_00028, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)"},
+    {VALIDATION_ERROR_00029, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'pQueueFamilyPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)"},
+    {VALIDATION_ERROR_00030, "For more information refer to Vulkan Spec Section '4.1. Physical Devices' which states 'If the value referenced by pQueueFamilyPropertyCount is not 0, and pQueueFamilyProperties is not NULL, pQueueFamilyProperties must be a pointer to an array of pQueueFamilyPropertyCount VkQueueFamilyProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceQueueFamilyProperties)"},
+    {VALIDATION_ERROR_00031, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)"},
+    {VALIDATION_ERROR_00032, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pCreateInfo must be a pointer to a valid VkDeviceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)"},
+    {VALIDATION_ERROR_00033, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)"},
+    {VALIDATION_ERROR_00034, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pDevice must be a pointer to a VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDevice)"},
+    {VALIDATION_ERROR_00035, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'The queueFamilyIndex member of any given element of pQueueCreateInfos must be unique within pQueueCreateInfos' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00036, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'sType must be VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00037, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00038, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00039, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'pQueueCreateInfos must be a pointer to an array of queueCreateInfoCount valid VkDeviceQueueCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00040, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If enabledLayerCount is not 0, ppEnabledLayerNames must be a pointer to an array of enabledLayerCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00041, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If enabledExtensionCount is not 0, ppEnabledExtensionNames must be a pointer to an array of enabledExtensionCount null-terminated strings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00042, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'If pEnabledFeatures is not NULL, pEnabledFeatures must be a pointer to a valid VkPhysicalDeviceFeatures structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00043, "For more information refer to Vulkan Spec Section '4.2.1. Device Creation' which states 'queueCreateInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceCreateInfo)"},
+    {VALIDATION_ERROR_00049, "For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'All child objects created on device must have been destroyed prior to destroying device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)"},
+    {VALIDATION_ERROR_00050, "For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If VkAllocationCallbacks were provided when device was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)"},
+    {VALIDATION_ERROR_00051, "For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If no VkAllocationCallbacks were provided when device was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)"},
+    {VALIDATION_ERROR_00052, "For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If device is not NULL, device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)"},
+    {VALIDATION_ERROR_00053, "For more information refer to Vulkan Spec Section '4.2.4. Device Destruction' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDevice)"},
+    {VALIDATION_ERROR_00054, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00055, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'sType must be VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00056, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00057, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00058, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueuePriorities must be a pointer to an array of queueCount float values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00059, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_00060, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueFamilyIndex must be one of the queue family indices specified when device was created, via the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)"},
+    {VALIDATION_ERROR_00061, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueIndex must be less than the number of queues created for the specified queue family index when device was created, via the queueCount member of the VkDeviceQueueCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)"},
+    {VALIDATION_ERROR_00062, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)"},
+    {VALIDATION_ERROR_00063, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'pQueue must be a pointer to a VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceQueue)"},
+    {VALIDATION_ERROR_00064, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)"},
+    {VALIDATION_ERROR_00065, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pCreateInfo must be a pointer to a valid VkCommandPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)"},
+    {VALIDATION_ERROR_00066, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)"},
+    {VALIDATION_ERROR_00067, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pCommandPool must be a pointer to a VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateCommandPool)"},
+    {VALIDATION_ERROR_00068, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'queueFamilyIndex must be the index of a queue family available in the calling commands device parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00069, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00070, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00071, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'flags must be a valid combination of VkCommandPoolCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00072, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'All VkCommandBuffer objects allocated from commandPool must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)"},
+    {VALIDATION_ERROR_00073, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)"},
+    {VALIDATION_ERROR_00074, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)"},
+    {VALIDATION_ERROR_00075, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'flags must be a valid combination of VkCommandPoolResetFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)"},
+    {VALIDATION_ERROR_00076, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'commandPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandPoolResetFlagBits)"},
+    {VALIDATION_ERROR_00077, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'All VkCommandBuffer objects allocated from commandPool must not be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00078, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If VkAllocationCallbacks were provided when commandPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00079, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If no VkAllocationCallbacks were provided when commandPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00080, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00081, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If commandPool is not VK_NULL_HANDLE, commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00082, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00083, "For more information refer to Vulkan Spec Section '5.1. Command Pools' which states 'If commandPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyCommandPool)"},
+    {VALIDATION_ERROR_00084, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)"},
+    {VALIDATION_ERROR_00085, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pAllocateInfo must be a pointer to a valid VkCommandBufferAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)"},
+    {VALIDATION_ERROR_00086, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pCommandBuffers must be a pointer to an array of pAllocateInfo::commandBufferCount VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateCommandBuffers)"},
+    {VALIDATION_ERROR_00087, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)"},
+    {VALIDATION_ERROR_00088, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)"},
+    {VALIDATION_ERROR_00089, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)"},
+    {VALIDATION_ERROR_00090, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)"},
+    {VALIDATION_ERROR_00091, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'level must be a valid VkCommandBufferLevel value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferLevel)"},
+    {VALIDATION_ERROR_00092, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)"},
+    {VALIDATION_ERROR_00093, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must have been allocated from a pool that was created with the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)"},
+    {VALIDATION_ERROR_00094, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)"},
+    {VALIDATION_ERROR_00095, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'flags must be a valid combination of VkCommandBufferResetFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferResetFlagBits)"},
+    {VALIDATION_ERROR_00096, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'All elements of pCommandBuffers must not be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00097, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'pCommandBuffers must be a pointer to an array of commandBufferCount VkCommandBuffer handles, each element of which must either be a valid handle or NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00098, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00099, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must be a valid VkCommandPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00100, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00101, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'commandPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00102, "For more information refer to Vulkan Spec Section '5.2. Command Buffer Allocation and Management' which states 'Each element of pCommandBuffers that is a valid handle must have been created, allocated, or retrieved from commandPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeCommandBuffers)"},
+    {VALIDATION_ERROR_00103, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must not be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00104, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must not currently be pending execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00105, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer was allocated from a VkCommandPool which did not have the VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, commandBuffer must be in the initial state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00106, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a secondary command buffer, the pInheritanceInfo member of pBeginInfo must be a valid VkCommandBufferInheritanceInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00107, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a secondary command buffer and either the occlusionQueryEnable member of the pInheritanceInfo member of pBeginInfo is VK_FALSE, or the precise occlusion queries feature is not enabled, the queryFlags member of the pInheritanceInfo member pBeginInfo must not contain VK_QUERY_CONTROL_PRECISE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00108, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00109, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pBeginInfo must be a pointer to a valid VkCommandBufferBeginInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBeginCommandBuffer)"},
+    {VALIDATION_ERROR_00110, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the renderPass member of pInheritanceInfo must be a valid VkRenderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00111, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the subpass member of pInheritanceInfo must be a valid subpass index within the renderPass member of pInheritanceInfo' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00112, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If flags contains VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the framebuffer member of pInheritanceInfo must be either VK_NULL_HANDLE, or a valid VkFramebuffer that is compatible with the renderPass member of pInheritanceInfo' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00113, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00114, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00115, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'flags must be a valid combination of VkCommandBufferUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferUsageFlagBits)"},
+    {VALIDATION_ERROR_00116, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the inherited queries feature is not enabled, occlusionQueryEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00117, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the inherited queries feature is enabled, queryFlags must be a valid combination of VkQueryControlFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00118, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If the pipeline statistics queries feature is not enabled, pipelineStatistics must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00119, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'sType must be VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00120, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00121, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'Both of framebuffer, and renderPass that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCommandBufferInheritanceInfo)"},
+    {VALIDATION_ERROR_00122, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)"},
+    {VALIDATION_ERROR_00123, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'If commandBuffer is a primary command buffer, there must not be an active render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)"},
+    {VALIDATION_ERROR_00124, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'All queries made active during the recording of commandBuffer must have been made inactive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)"},
+    {VALIDATION_ERROR_00125, "For more information refer to Vulkan Spec Section '5.3. Command Buffer Recording' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEndCommandBuffer)"},
+    {VALIDATION_ERROR_00126, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00127, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00128, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00129, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If submitCount is not 0, pSubmits must be a pointer to an array of submitCount valid VkSubmitInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00130, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00131, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueSubmit)"},
+    {VALIDATION_ERROR_00132, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pSignalSemaphores must currently be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00133, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must either have been recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00134, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must be in the executable state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00135, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers contains commands that execute secondary command buffers, those secondary command buffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00136, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers was recorded with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, it must not have been previously submitted without re-recording that command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00137, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If any given element of pCommandBuffers contains commands that execute secondary command buffers recorded with VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, each such secondary command buffer must not have been previously submitted without re-recording that command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00138, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must not contain commands that execute a secondary command buffer, if that secondary command buffer has been recorded in another primary command buffer after it was recorded into this VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00139, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must have been allocated from a VkCommandPool that was created for the same queue family that the calling commands queue belongs to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00140, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of pCommandBuffers must not have been allocated with VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00141, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Any given element of VkSemaphore in pWaitSemaphores must refer to a prior signal of that VkSemaphore that will not be consumed by any other wait on that semaphore' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00142, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If the geometry shaders feature is not enabled, any given element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00143, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If the tessellation shaders feature is not enabled, any given element of pWaitDstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00144, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'sType must be VK_STRUCTURE_TYPE_SUBMIT_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00145, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00146, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If waitSemaphoreCount is not 0, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00147, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If waitSemaphoreCount is not 0, pWaitDstStageMask must be a pointer to an array of waitSemaphoreCount valid combinations of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00148, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Each element of pWaitDstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00149, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If commandBufferCount is not 0, pCommandBuffers must be a pointer to an array of commandBufferCount valid VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00150, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If signalSemaphoreCount is not 0, pSignalSemaphores must be a pointer to an array of signalSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00151, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Each of the elements of pCommandBuffers, the elements of pSignalSemaphores, and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubmitInfo)"},
+    {VALIDATION_ERROR_00152, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_PRIMARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00153, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated with a level of VK_COMMAND_BUFFER_LEVEL_SECONDARY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00154, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not be already pending execution in commandBuffer, or appear twice in pCommandBuffers, unless it was recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00155, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not be already pending execution in any other VkCommandBuffer, unless it was recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00156, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must be in the executable state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00157, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must have been allocated from a VkCommandPool that was created for the same queue family as the VkCommandPool from which commandBuffer was allocated' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00158, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must have been begun with the contents parameter of vkCmdBeginRenderPass set to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00159, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00160, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'pCommandBuffers must be a pointer to an array of commandBufferCount valid VkCommandBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00161, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00162, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00163, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00164, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'commandBufferCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00165, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Both of commandBuffer, and the elements of pCommandBuffers must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_00166, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)"},
+    {VALIDATION_ERROR_00167, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pCreateInfo must be a pointer to a valid VkFenceCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)"},
+    {VALIDATION_ERROR_00168, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)"},
+    {VALIDATION_ERROR_00169, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFence must be a pointer to a VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFence)"},
+    {VALIDATION_ERROR_00170, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'sType must be VK_STRUCTURE_TYPE_FENCE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)"},
+    {VALIDATION_ERROR_00171, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)"},
+    {VALIDATION_ERROR_00172, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'flags must be a valid combination of VkFenceCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkFenceCreateFlagBits)"},
+    {VALIDATION_ERROR_00173, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must not be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00174, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If VkAllocationCallbacks were provided when fence was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00175, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If no VkAllocationCallbacks were provided when fence was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00176, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00177, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00178, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00179, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'If fence is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFence)"},
+    {VALIDATION_ERROR_00180, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)"},
+    {VALIDATION_ERROR_00181, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)"},
+    {VALIDATION_ERROR_00182, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fence must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetFenceStatus)"},
+    {VALIDATION_ERROR_00183, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Any given element of pFences must not currently be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)"},
+    {VALIDATION_ERROR_00184, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)"},
+    {VALIDATION_ERROR_00185, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFences must be a pointer to an array of fenceCount valid VkFence handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)"},
+    {VALIDATION_ERROR_00186, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fenceCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)"},
+    {VALIDATION_ERROR_00187, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Each element of pFences must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetFences)"},
+    {VALIDATION_ERROR_00188, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)"},
+    {VALIDATION_ERROR_00189, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'pFences must be a pointer to an array of fenceCount valid VkFence handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)"},
+    {VALIDATION_ERROR_00190, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'fenceCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)"},
+    {VALIDATION_ERROR_00191, "For more information refer to Vulkan Spec Section '6.1. Fences' which states 'Each element of pFences must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#synchronization-fences-devicewrites)"},
+    {VALIDATION_ERROR_00192, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)"},
+    {VALIDATION_ERROR_00193, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pCreateInfo must be a pointer to a valid VkSemaphoreCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)"},
+    {VALIDATION_ERROR_00194, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)"},
+    {VALIDATION_ERROR_00195, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pSemaphore must be a pointer to a VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSemaphore)"},
+    {VALIDATION_ERROR_00196, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'sType must be VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)"},
+    {VALIDATION_ERROR_00197, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)"},
+    {VALIDATION_ERROR_00198, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSemaphoreCreateInfo)"},
+    {VALIDATION_ERROR_00199, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'semaphore must not be associated with any queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00200, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If VkAllocationCallbacks were provided when semaphore was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00201, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If no VkAllocationCallbacks were provided when semaphore was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00202, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00203, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00204, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00205, "For more information refer to Vulkan Spec Section '6.2. Semaphores' which states 'If semaphore is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySemaphore)"},
+    {VALIDATION_ERROR_00206, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)"},
+    {VALIDATION_ERROR_00207, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'pCreateInfo must be a pointer to a valid VkEventCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)"},
+    {VALIDATION_ERROR_00208, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)"},
+    {VALIDATION_ERROR_00209, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'pEvent must be a pointer to a VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateEvent)"},
+    {VALIDATION_ERROR_00210, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'sType must be VK_STRUCTURE_TYPE_EVENT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)"},
+    {VALIDATION_ERROR_00211, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)"},
+    {VALIDATION_ERROR_00212, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkEventCreateInfo)"},
+    {VALIDATION_ERROR_00213, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'All submitted commands that refer to event must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00214, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If VkAllocationCallbacks were provided when event was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00215, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If no VkAllocationCallbacks were provided when event was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00216, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00217, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If event is not VK_NULL_HANDLE, event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00218, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00219, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If event is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyEvent)"},
+    {VALIDATION_ERROR_00220, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)"},
+    {VALIDATION_ERROR_00221, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)"},
+    {VALIDATION_ERROR_00222, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.8.25)"},
+    {VALIDATION_ERROR_00223, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)"},
+    {VALIDATION_ERROR_00224, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)"},
+    {VALIDATION_ERROR_00225, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkSetEvent)"},
+    {VALIDATION_ERROR_00226, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must not be waited on by a vkCmdWaitEvents command that is currently executing' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)"},
+    {VALIDATION_ERROR_00227, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)"},
+    {VALIDATION_ERROR_00228, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)"},
+    {VALIDATION_ERROR_00229, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetEvent)"},
+    {VALIDATION_ERROR_00230, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00231, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00232, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00233, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00234, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00235, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00236, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00237, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00238, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00239, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and event must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetEvent)"},
+    {VALIDATION_ERROR_00240, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00241, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, stageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00242, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'When this command executes, event must not be waited on by a vkCmdWaitEvents command that is currently executing' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00243, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00244, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'event must be a valid VkEvent handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00245, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00246, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'stageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00247, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00248, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00249, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00250, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and event must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetEvent)"},
+    {VALIDATION_ERROR_00251, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must be the bitwise OR of the stageMask parameter used in previous calls to vkCmdSetEvent with any of the members of pEvents and VK_PIPELINE_STAGE_HOST_BIT if any of the members of pEvents was set using vkSetEvent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00252, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00253, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'pEvents must be a pointer to an array of eventCount valid VkEvent handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00254, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00255, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00256, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00257, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00258, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If memoryBarrierCount is not 0, pMemoryBarriers must be a pointer to an array of memoryBarrierCount valid VkMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00259, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If bufferMemoryBarrierCount is not 0, pBufferMemoryBarriers must be a pointer to an array of bufferMemoryBarrierCount valid VkBufferMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00260, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If imageMemoryBarrierCount is not 0, pImageMemoryBarriers must be a pointer to an array of imageMemoryBarrierCount valid VkImageMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00261, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00262, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00263, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'eventCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00264, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'Both of commandBuffer, and the elements of pEvents must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_00265, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00266, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00267, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00268, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00269, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the render pass must have been created with a VkSubpassDependency instance in pDependencies that expresses a dependency from the current subpass to itself. Additionally:srcStageMask must contain a subset of the bit values in the srcStageMask member of that instance of VkSubpassDependencydstStageMask must contain a subset of the bit values in the dstStageMask member of that instance of VkSubpassDependencyThe srcAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the srcAccessMask member of that instance of VkSubpassDependencyThe dstAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the dstAccessMask member of that instance of VkSubpassDependencydependencyFlags must be equal to the dependencyFlags member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00270, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00271, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00272, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00273, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00274, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00275, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dependencyFlags must be a valid combination of VkDependencyFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00276, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If memoryBarrierCount is not 0, pMemoryBarriers must be a pointer to an array of memoryBarrierCount valid VkMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00277, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If bufferMemoryBarrierCount is not 0, pBufferMemoryBarriers must be a pointer to an array of bufferMemoryBarrierCount valid VkBufferMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00278, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If imageMemoryBarrierCount is not 0, pImageMemoryBarriers must be a pointer to an array of imageMemoryBarrierCount valid VkImageMemoryBarrier structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00279, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00280, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_00281, "For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)"},
+    {VALIDATION_ERROR_00282, "For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)"},
+    {VALIDATION_ERROR_00283, "For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)"},
+    {VALIDATION_ERROR_00284, "For more information refer to Vulkan Spec Section '6.5.4. Global Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#id-1.8.10.15.14)"},
+    {VALIDATION_ERROR_00285, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00286, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00287, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to than the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00288, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, srcQueueFamilyIndex and dstQueueFamilyIndex must both be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00289, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, srcQueueFamilyIndex and dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see Section 4.3.1, Queue Family Properties)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00290, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'If buffer was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are valid queue families, at least one of them must be the same as the family of the queue that will execute this barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00291, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00292, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00293, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00294, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00295, "For more information refer to Vulkan Spec Section '6.5.5. Buffer Memory Barriers' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferMemoryBarrier)"},
+    {VALIDATION_ERROR_00296, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'oldLayout must be VK_IMAGE_LAYOUT_UNDEFINED or the current layout of the image subresources affected by the barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00297, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'newLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00298, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_CONCURRENT, srcQueueFamilyIndex and dstQueueFamilyIndex must both be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00299, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, srcQueueFamilyIndex and dstQueueFamilyIndex must either both be VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see Section 4.3.1, Queue Family Properties)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00300, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image was created with a sharing mode of VK_SHARING_MODE_EXCLUSIVE, and srcQueueFamilyIndex and dstQueueFamilyIndex are valid queue families, at least one of them must be the same as the family of the queue that will execute this barrier' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00301, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'subresourceRange must be a valid image subresource range for the image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00302, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If image has a depth/stencil format with both depth and stencil components, then aspectMask member of subresourceRange must include both VK_IMAGE_ASPECT_DEPTH_BIT and VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00303, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00304, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL then image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00305, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then image must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00306, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then image must have been created with VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00307, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00308, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'If either oldLayout or newLayout is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00309, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00310, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00311, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00312, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00313, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'oldLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00314, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'newLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00315, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00316, "For more information refer to Vulkan Spec Section '6.5.6. Image Memory Barriers' which states 'subresourceRange must be a valid VkImageSubresourceRange structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageMemoryBarrier)"},
+    {VALIDATION_ERROR_00317, "For more information refer to Vulkan Spec Section '6.5.7. Wait Idle Operations' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueWaitIdle)"},
+    {VALIDATION_ERROR_00318, "For more information refer to Vulkan Spec Section '6.5.7. Wait Idle Operations' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDeviceWaitIdle)"},
+    {VALIDATION_ERROR_00319, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)"},
+    {VALIDATION_ERROR_00320, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pCreateInfo must be a pointer to a valid VkRenderPassCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)"},
+    {VALIDATION_ERROR_00321, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)"},
+    {VALIDATION_ERROR_00322, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pRenderPass must be a pointer to a VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateRenderPass)"},
+    {VALIDATION_ERROR_00323, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any two subpasses operate on attachments with overlapping ranges of the same VkDeviceMemory object, and at least one subpass writes to that area of VkDeviceMemory, a subpass dependency must be included (either directly or via some intermediate subpasses) between them' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00324, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, or the attachment indexed by any element of pPreserveAttachments in any given element of pSubpasses is bound to a range of a VkDeviceMemory object that overlaps with any other attachment in any subpass (including the same subpass), the VkAttachmentDescription structures describing them must include VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00325, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the attachment member of any element of pInputAttachments, pColorAttachments, pResolveAttachments or pDepthStencilAttachment, or any element of pPreserveAttachments in any given element of pSubpasses is not VK_ATTACHMENT_UNUSED, it must be less than attachmentCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00326, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'The value of any element of the pPreserveAttachments member in any given element of pSubpasses must not be VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00327, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'sType must be VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00328, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00329, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00330, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkAttachmentDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00331, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pSubpasses must be a pointer to an array of subpassCount valid VkSubpassDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00332, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If dependencyCount is not 0, pDependencies must be a pointer to an array of dependencyCount valid VkSubpassDependency structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00333, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'subpassCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassCreateInfo)"},
+    {VALIDATION_ERROR_00334, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'finalLayout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00335, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be a valid combination of VkAttachmentDescriptionFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00336, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00337, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00338, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'loadOp must be a valid VkAttachmentLoadOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00339, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'storeOp must be a valid VkAttachmentStoreOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00340, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'stencilLoadOp must be a valid VkAttachmentLoadOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00341, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'stencilStoreOp must be a valid VkAttachmentStoreOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00342, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'initialLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00343, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'finalLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-aliasing)"},
+    {VALIDATION_ERROR_00347, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pipelineBindPoint must be VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00348, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'colorAttachmentCount must be less than or equal to VkPhysicalDeviceLimits::maxColorAttachments' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00349, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the first use of an attachment in this render pass is as an input attachment, and the attachment is not also used as a color or depth/stencil attachment in the same subpass, then loadOp must not be VK_ATTACHMENT_LOAD_OP_CLEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00350, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pResolveAttachments is not NULL, for each resolve attachment that does not have the value VK_ATTACHMENT_UNUSED, the corresponding color attachment must not have the value VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00351, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pResolveAttachments is not NULL, the sample count of each element of pColorAttachments must be anything other than VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00352, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pResolveAttachments must have a sample count of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00353, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pResolveAttachments must have the same VkFormat as its corresponding color attachment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00354, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'All attachments in pColorAttachments and pDepthStencilAttachment that are not VK_ATTACHMENT_UNUSED must have the same sample count' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00355, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any input attachments are VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must not access those input attachments from the fragment shader' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00356, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'The attachment member of any element of pPreserveAttachments must not be VK_ATTACHMENT_UNUSED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00357, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'Any given element of pPreserveAttachments must not also be an element of any other member of the subpass description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00358, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If any attachment is used as both an input attachment and a color or depth/stencil attachment, then each use must use the same layout' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00359, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00360, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00361, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If inputAttachmentCount is not 0, pInputAttachments must be a pointer to an array of inputAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00362, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If colorAttachmentCount is not 0, pColorAttachments must be a pointer to an array of colorAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00363, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If colorAttachmentCount is not 0, and pResolveAttachments is not NULL, pResolveAttachments must be a pointer to an array of colorAttachmentCount valid VkAttachmentReference structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00364, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pDepthStencilAttachment is not NULL, pDepthStencilAttachment must be a pointer to a valid VkAttachmentReference structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00365, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If preserveAttachmentCount is not 0, pPreserveAttachments must be a pointer to an array of preserveAttachmentCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassDescription)"},
+    {VALIDATION_ERROR_00366, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'layout must not be VK_IMAGE_LAYOUT_UNDEFINED or VK_IMAGE_LAYOUT_PREINITIALIZED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAttachmentReference)"},
+    {VALIDATION_ERROR_00367, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'layout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAttachmentReference)"},
+    {VALIDATION_ERROR_00368, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00369, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00370, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00371, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00372, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcSubpass must be less than or equal to dstSubpass, unless one of them is VK_SUBPASS_EXTERNAL, to avoid cyclic dependencies and ensure a valid execution order' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00373, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcSubpass and dstSubpass must not both be equal to VK_SUBPASS_EXTERNAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00374, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If srcSubpass is equal to dstSubpass, srcStageMask and dstStageMask must only contain one of VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, or VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00375, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If srcSubpass is equal to dstSubpass, the highest bit value included in srcStageMask must be less than or equal to the lowest bit value in dstStageMask' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00376, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00377, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00378, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstStageMask must be a valid combination of VkPipelineStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00379, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstStageMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00380, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'srcAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00381, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dstAccessMask must be a valid combination of VkAccessFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00382, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'dependencyFlags must be a valid combination of VkDependencyFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDependencyFlagBits)"},
+    {VALIDATION_ERROR_00393, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'All submitted commands that refer to renderPass must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00394, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If VkAllocationCallbacks were provided when renderPass was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00395, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If no VkAllocationCallbacks were provided when renderPass was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00396, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00397, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If renderPass is not VK_NULL_HANDLE, renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00398, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00399, "For more information refer to Vulkan Spec Section '7.1. Render Pass Creation' which states 'If renderPass is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyRenderPass)"},
+    {VALIDATION_ERROR_00400, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)"},
+    {VALIDATION_ERROR_00401, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pCreateInfo must be a pointer to a valid VkFramebufferCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)"},
+    {VALIDATION_ERROR_00402, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)"},
+    {VALIDATION_ERROR_00403, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pFramebuffer must be a pointer to a VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateFramebuffer)"},
+    {VALIDATION_ERROR_00404, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'attachmentCount must be equal to the attachment count specified in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00405, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as a color attachment or resolve attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00406, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as a depth/stencil attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00407, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments that is used as an input attachment by renderPass must have been created with a usage value including VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00408, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with an VkFormat value that matches the VkFormat specified by the corresponding VkAttachmentDescription in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00409, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with a samples value that matches the samples value specified by the corresponding VkAttachmentDescription in renderPass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00410, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have dimensions at least as large as the corresponding framebuffer dimension' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00411, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must only specify a single mip level' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00412, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Any given element of pAttachments must have been created with the identity swizzle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00413, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'width must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferWidth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00414, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'height must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferHeight' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00415, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'layers must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferLayers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00416, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'sType must be VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00417, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00418, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00419, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00420, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkImageView handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00421, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'Both of renderPass, and the elements of pAttachments that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#renderpass-noattachments)"},
+    {VALIDATION_ERROR_00422, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'All submitted commands that refer to framebuffer must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00423, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If VkAllocationCallbacks were provided when framebuffer was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00424, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If no VkAllocationCallbacks were provided when framebuffer was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00425, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00426, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If framebuffer is not VK_NULL_HANDLE, framebuffer must be a valid VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00427, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00428, "For more information refer to Vulkan Spec Section '7.3. Framebuffers' which states 'If framebuffer is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyFramebuffer)"},
+    {VALIDATION_ERROR_00429, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00430, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00431, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_SAMPLED_BIT or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00432, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00433, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout or finalLayout member of the VkAttachmentDescription structures or the layout member of the VkAttachmentReference structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00434, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If any of the initialLayout members of the VkAttachmentDescription structures specified when creating the render pass specified in the renderPass member of pRenderPassBegin is not VK_IMAGE_LAYOUT_UNDEFINED, then each such initialLayout must be equal to the current layout of the corresponding attachment image subresource of the framebuffer specified in the framebuffer member of pRenderPassBegin' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00435, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00436, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pRenderPassBegin must be a pointer to a valid VkRenderPassBeginInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00437, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'contents must be a valid VkSubpassContents value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00438, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00439, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00440, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00441, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSubpassContents)"},
+    {VALIDATION_ERROR_00442, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'clearValueCount must be greater than the largest attachment index in renderPass that specifies a loadOp (or stencilLoadOp, if the attachment has a depth/stencil format) of VK_ATTACHMENT_LOAD_OP_CLEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00443, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'sType must be VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00444, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00445, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00446, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'framebuffer must be a valid VkFramebuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00447, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'If clearValueCount is not 0, pClearValues must be a pointer to an array of clearValueCount valid VkClearValue unions' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00448, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'Both of framebuffer, and renderPass must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_00449, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)"},
+    {VALIDATION_ERROR_00450, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)"},
+    {VALIDATION_ERROR_00451, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'pGranularity must be a pointer to a VkExtent2D structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)"},
+    {VALIDATION_ERROR_00452, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetRenderAreaGranularity)"},
+    {VALIDATION_ERROR_00453, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The current subpass index must be less than the number of subpasses in the render pass minus one' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00454, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00455, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'contents must be a valid VkSubpassContents value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00456, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00457, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00458, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00459, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdNextSubpass)"},
+    {VALIDATION_ERROR_00460, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The current subpass index must be equal to the number of subpasses in the render pass minus one' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00461, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00462, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00463, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00464, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00465, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'commandBuffer must be a primary VkCommandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdEndRenderPass)"},
+    {VALIDATION_ERROR_00466, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)"},
+    {VALIDATION_ERROR_00467, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCreateInfo must be a pointer to a valid VkShaderModuleCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)"},
+    {VALIDATION_ERROR_00468, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)"},
+    {VALIDATION_ERROR_00469, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pShaderModule must be a pointer to a VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateShaderModule)"},
+    {VALIDATION_ERROR_00470, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'codeSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00471, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'codeSize must be a multiple of 4. If the VK_NV_glsl_shader extension is enabled and pCode references GLSL code codeSize can be a multiple of 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00472, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must point to valid SPIR-V code, formatted and packed as described by the Khronos SPIR-V Specification. If the VK_NV_glsl_shader extension is enabled pCode can instead reference valid GLSL code and must be written to the GL_KHR_vulkan_glsl extension specification' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00473, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must adhere to the validation rules described by the Validation Rules within a Module section of the SPIR-V Environment appendix. If the VK_NV_glsl_shader extension is enabled pCode can be valid GLSL code with respect to the GL_KHR_vulkan_glsl GLSL extension specification' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00474, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must declare the Shader capability for SPIR-V code' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00475, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'sType must be VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00476, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00477, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00478, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must be a pointer to an array of $codeSize /over 4$ uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_00479, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If VkAllocationCallbacks were provided when shaderModule was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00480, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If no VkAllocationCallbacks were provided when shaderModule was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00481, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00482, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If shaderModule is not VK_NULL_HANDLE, shaderModule must be a valid VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00483, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00484, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If shaderModule is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyShaderModule)"},
+    {VALIDATION_ERROR_00485, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the flags member of any given element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1, basePipelineIndex must be less than the index into pCreateInfos that corresponds to that element' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00486, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00487, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00488, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pCreateInfos must be a pointer to an array of createInfoCount valid VkComputePipelineCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00489, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00490, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pPipelines must be a pointer to an array of createInfoCount VkPipeline handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00491, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'createInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00492, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateComputePipelines)"},
+    {VALIDATION_ERROR_00493, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, basePipelineHandle must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00494, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, it must be a valid index into the calling commands pCreateInfos parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00495, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineIndex must be -1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00496, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineHandle must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00497, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, it must be a valid handle to a compute VkPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00498, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'The stage member of stage must be VK_SHADER_STAGE_COMPUTE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00499, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'The shader code for the entry point identified by stage and the rest of the state identified by this structure must adhere to the pipeline linking rules described in the Shader Interfaces chapter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00500, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'layout must be consistent with the layout of the compute shader specified in stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00501, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00502, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00503, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'flags must be a valid combination of VkPipelineCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00504, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must be a valid VkPipelineShaderStageCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00505, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00506, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'Both of basePipelineHandle, and layout that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkComputePipelineCreateInfo)"},
+    {VALIDATION_ERROR_00507, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the geometry shaders feature is not enabled, stage must not be VK_SHADER_STAGE_GEOMETRY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00508, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the tessellation shaders feature is not enabled, stage must not be VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00509, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must not be VK_SHADER_STAGE_ALL_GRAPHICS, or VK_SHADER_STAGE_ALL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00510, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pName must be the name of an OpEntryPoint in module with an execution model that matches stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00511, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00512, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00513, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00514, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'stage must be a valid VkShaderStageFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00515, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'module must be a valid VkShaderModule handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00516, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'pName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00517, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If pSpecializationInfo is not NULL, pSpecializationInfo must be a pointer to a valid VkSpecializationInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_00518, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the flags member of any given element of pCreateInfos contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the basePipelineIndex member of that same element is not -1, basePipelineIndex must be less than the index into pCreateInfos that corresponds to that element' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00519, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00520, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00521, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pCreateInfos must be a pointer to an array of createInfoCount valid VkGraphicsPipelineCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00522, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00523, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pPipelines must be a pointer to an array of createInfoCount VkPipeline handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00524, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'createInfoCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00525, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateGraphicsPipelines)"},
+    {VALIDATION_ERROR_00526, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, basePipelineHandle must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00527, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineIndex is not -1, it must be a valid index into the calling commands pCreateInfos parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00528, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineIndex must be -1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00529, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, basePipelineHandle must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00530, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If flags contains the VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and basePipelineHandle is not VK_NULL_HANDLE, it must be a valid handle to a graphics VkPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00531, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of each element of pStages must be unique' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00532, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of one element of pStages must be VK_SHADER_STAGE_VERTEX_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00533, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The stage member of any given element of pStages must not be VK_SHADER_STAGE_COMPUTE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00534, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage, it must include a tessellation evaluation shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00535, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation evaluation shader stage, it must include a tessellation control shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00536, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pTessellationState must not be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00537, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00538, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00539, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00540, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'flags must be a valid combination of VkPipelineCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00541, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pStages must be a pointer to an array of stageCount valid VkPipelineShaderStageCreateInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00542, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pVertexInputState must be a pointer to a valid VkPipelineVertexInputStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00543, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pInputAssemblyState must be a pointer to a valid VkPipelineInputAssemblyStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00544, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pRasterizationState must be a pointer to a valid VkPipelineRasterizationStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00545, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pDynamicState is not NULL, pDynamicState must be a pointer to a valid VkPipelineDynamicStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00546, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00547, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'renderPass must be a valid VkRenderPass handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00548, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'stageCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00549, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'Each of basePipelineHandle, layout, and renderPass that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_00550, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)"},
+    {VALIDATION_ERROR_00551, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)"},
+    {VALIDATION_ERROR_00552, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)"},
+    {VALIDATION_ERROR_00553, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'pDynamicStates must be a pointer to an array of dynamicStateCount valid VkDynamicState values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)"},
+    {VALIDATION_ERROR_00554, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'dynamicStateCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDynamicStateCreateInfo)"},
+    {VALIDATION_ERROR_00555, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'All submitted commands that refer to pipeline must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00556, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If VkAllocationCallbacks were provided when pipeline was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00557, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If no VkAllocationCallbacks were provided when pipeline was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00558, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00559, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pipeline is not VK_NULL_HANDLE, pipeline must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00560, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00561, "For more information refer to Vulkan Spec Section '9.3. Pipeline destruction' which states 'If pipeline is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipeline)"},
+    {VALIDATION_ERROR_00562, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)"},
+    {VALIDATION_ERROR_00563, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pCreateInfo must be a pointer to a valid VkPipelineCacheCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)"},
+    {VALIDATION_ERROR_00564, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)"},
+    {VALIDATION_ERROR_00565, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pPipelineCache must be a pointer to a VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineCache)"},
+    {VALIDATION_ERROR_00566, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, it must be equal to the size of pInitialData, as returned by vkGetPipelineCacheData when pInitialData was originally retrieved' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_00567, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_00568, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_00569, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_00570, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, pInitialData must be a pointer to an array of initialDataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_00571, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must not appear in the list of source caches' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00572, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00573, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00574, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pSrcCaches must be a pointer to an array of srcCacheCount valid VkPipelineCache handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00575, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'srcCacheCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00576, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'dstCache must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00577, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'Each element of pSrcCaches must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkMergePipelineCaches)"},
+    {VALIDATION_ERROR_00578, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)"},
+    {VALIDATION_ERROR_00579, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)"},
+    {VALIDATION_ERROR_00580, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pDataSize must be a pointer to a size_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)"},
+    {VALIDATION_ERROR_00581, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If the value referenced by pDataSize is not 0, and pData is not NULL, pData must be a pointer to an array of pDataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)"},
+    {VALIDATION_ERROR_00582, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'pipelineCache must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheHeaderVersion)"},
+    {VALIDATION_ERROR_00583, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If VkAllocationCallbacks were provided when pipelineCache was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00584, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If no VkAllocationCallbacks were provided when pipelineCache was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00585, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00586, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pipelineCache is not VK_NULL_HANDLE, pipelineCache must be a valid VkPipelineCache handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00587, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00588, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If pipelineCache is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineCache)"},
+    {VALIDATION_ERROR_00589, "For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'The offset member of any given element of pMapEntries must be less than dataSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)"},
+    {VALIDATION_ERROR_00590, "For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'For any given element of pMapEntries, size must be less than or equal to dataSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)"},
+    {VALIDATION_ERROR_00591, "For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'If mapEntryCount is not 0, pMapEntries must be a pointer to an array of mapEntryCount valid VkSpecializationMapEntry structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)"},
+    {VALIDATION_ERROR_00592, "For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'If dataSize is not 0, pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationInfo)"},
+    {VALIDATION_ERROR_00593, "For more information refer to Vulkan Spec Section '9.7. Specialization Constants' which states 'For a constantID specialization constant declared in a shader, size must match the byte size of the constantID. If the specialization constant is of type boolean, size must be the byte size of VkBool32' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSpecializationMapEntry)"},
+    {VALIDATION_ERROR_00594, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, the VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00595, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00596, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_COMPUTE, pipeline must be a compute pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00597, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If pipelineBindPoint is VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline must be a graphics pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00598, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'If the variable multisample rate feature is not supported, pipeline is a graphics pipeline, the current subpass has no attachments, and this is not the first call to this function with a graphics pipeline after transitioning to the current subpass, then the sample count specified by this pipeline must match that set in the previous pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00599, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00600, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00601, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'pipeline must be a valid VkPipeline handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00602, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00603, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00604, "For more information refer to Vulkan Spec Section '9.8. Pipeline Binding' which states 'Both of commandBuffer, and pipeline must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineBindPoint)"},
+    {VALIDATION_ERROR_00605, "For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnAllocation must be a pointer to a valid user-defined PFN_vkAllocationFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)"},
+    {VALIDATION_ERROR_00606, "For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnReallocation must be a pointer to a valid user-defined PFN_vkReallocationFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)"},
+    {VALIDATION_ERROR_00607, "For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'pfnFree must be a pointer to a valid user-defined PFN_vkFreeFunction' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)"},
+    {VALIDATION_ERROR_00608, "For more information refer to Vulkan Spec Section '10.1. Host Memory' which states 'If either of pfnInternalAllocation or pfnInternalFree is not NULL, both must be valid callbacks' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAllocationCallbacks)"},
+    {VALIDATION_ERROR_00609, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMemoryProperties)"},
+    {VALIDATION_ERROR_00610, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pMemoryProperties must be a pointer to a VkPhysicalDeviceMemoryProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMemoryProperties)"},
+    {VALIDATION_ERROR_00611, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'The number of currently valid memory objects, allocated from device, must be less than VkPhysicalDeviceLimits::maxMemoryAllocationCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)"},
+    {VALIDATION_ERROR_00612, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)"},
+    {VALIDATION_ERROR_00613, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pAllocateInfo must be a pointer to a valid VkMemoryAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)"},
+    {VALIDATION_ERROR_00614, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)"},
+    {VALIDATION_ERROR_00615, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pMemory must be a pointer to a VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateMemory)"},
+    {VALIDATION_ERROR_00616, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'allocationSize must be less than or equal to the amount of memory available to the VkMemoryHeap specified by memoryTypeIndex and the calling commands VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)"},
+    {VALIDATION_ERROR_00617, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'allocationSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)"},
+    {VALIDATION_ERROR_00618, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)"},
+    {VALIDATION_ERROR_00619, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationMemoryAllocateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMemoryAllocateInfo)"},
+    {VALIDATION_ERROR_00620, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'All submitted commands that refer to memory (via images or buffers) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)"},
+    {VALIDATION_ERROR_00621, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)"},
+    {VALIDATION_ERROR_00622, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)"},
+    {VALIDATION_ERROR_00623, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)"},
+    {VALIDATION_ERROR_00624, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If memory is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeMemory)"},
+    {VALIDATION_ERROR_00625, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must not currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00626, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'offset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00627, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00628, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to the size of the memory minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00629, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00630, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00631, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00632, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00633, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'ppData must be a pointer to a pointer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00634, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#memory-device-hostaccess-hazards)"},
+    {VALIDATION_ERROR_00635, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00636, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pMemoryRanges must be a pointer to an array of memoryRangeCount valid VkMappedMemoryRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00637, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memoryRangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFlushMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00638, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00639, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pMemoryRanges must be a pointer to an array of memoryRangeCount valid VkMappedMemoryRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00640, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memoryRangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkInvalidateMappedMemoryRanges)"},
+    {VALIDATION_ERROR_00641, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00642, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, offset and size must specify a range contained within the currently mapped range of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00643, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is equal to VK_WHOLE_SIZE, offset must be within the currently mapped range of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00644, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'offset must be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00645, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'If size is not equal to VK_WHOLE_SIZE, size must be a multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00646, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'sType must be VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00647, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00648, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMappedMemoryRange)"},
+    {VALIDATION_ERROR_00649, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must currently be mapped' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)"},
+    {VALIDATION_ERROR_00650, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)"},
+    {VALIDATION_ERROR_00651, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)"},
+    {VALIDATION_ERROR_00652, "For more information refer to Vulkan Spec Section '10.2.1. Host Access to Device Memory Objects' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUnmapMemory)"},
+    {VALIDATION_ERROR_00653, "For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must have been created with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)"},
+    {VALIDATION_ERROR_00654, "For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)"},
+    {VALIDATION_ERROR_00655, "For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)"},
+    {VALIDATION_ERROR_00656, "For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'pCommittedMemoryInBytes must be a pointer to a VkDeviceSize value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)"},
+    {VALIDATION_ERROR_00657, "For more information refer to Vulkan Spec Section '10.2.2. Lazily Allocated Memory' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDeviceMemoryCommitment)"},
+    {VALIDATION_ERROR_00658, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the flags member of pCreateInfo includes VK_BUFFER_CREATE_SPARSE_BINDING_BIT, creating this VkBuffer must not cause the total required sparse memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)"},
+    {VALIDATION_ERROR_00659, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)"},
+    {VALIDATION_ERROR_00660, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pCreateInfo must be a pointer to a valid VkBufferCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)"},
+    {VALIDATION_ERROR_00661, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)"},
+    {VALIDATION_ERROR_00662, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pBuffer must be a pointer to a VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBuffer)"},
+    {VALIDATION_ERROR_00663, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00664, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00665, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00666, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse bindings feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00667, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse buffer residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00668, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If the sparse aliased residency feature is not enabled, flags must not contain VK_BUFFER_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00669, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If flags contains VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_BUFFER_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00670, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00671, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationBufferCreateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00672, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'flags must be a valid combination of VkBufferCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00673, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'usage must be a valid combination of VkBufferUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00674, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00675, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferCreateFlagBits)"},
+    {VALIDATION_ERROR_00676, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'All submitted commands that refer to buffer, either directly or via a VkBufferView, must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00677, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If VkAllocationCallbacks were provided when buffer was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00678, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If no VkAllocationCallbacks were provided when buffer was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00679, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00680, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00681, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00682, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If buffer is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBuffer)"},
+    {VALIDATION_ERROR_00683, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)"},
+    {VALIDATION_ERROR_00684, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pCreateInfo must be a pointer to a valid VkBufferViewCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)"},
+    {VALIDATION_ERROR_00685, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)"},
+    {VALIDATION_ERROR_00686, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pView must be a pointer to a VkBufferView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateBufferView)"},
+    {VALIDATION_ERROR_00687, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00688, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'offset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00689, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If range is not equal to VK_WHOLE_SIZE:range must be greater than 0range must be a multiple of the element size of formatrange divided by the element size of format, must be less than or equal to VkPhysicalDeviceLimits::maxTexelBufferElementsthe sum of offset and range must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00690, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00691, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range must be a multiple of the element size of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00692, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'range divided by the element size of format, must be less than or equal to VkPhysicalDeviceLimits::maxTexelBufferElements' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00693, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'the sum of offset and range must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00694, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'buffer must have been created with a usage value containing at least one of VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00695, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If buffer was created with usage containing VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, format must be supported for uniform texel buffers, as specified by the VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00696, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'sType must be VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00697, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00698, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00699, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00700, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_00701, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'All submitted commands that refer to bufferView must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00702, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If VkAllocationCallbacks were provided when bufferView was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00703, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If no VkAllocationCallbacks were provided when bufferView was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00704, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00705, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If bufferView is not VK_NULL_HANDLE, bufferView must be a valid VkBufferView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00706, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00707, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If bufferView is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyBufferView)"},
+    {VALIDATION_ERROR_00708, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the flags member of pCreateInfo includes VK_IMAGE_CREATE_SPARSE_BINDING_BIT, creating this VkImage must not cause the total required sparse memory for all currently valid sparse resources on the device to exceed VkPhysicalDeviceLimits::sparseAddressSpaceSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)"},
+    {VALIDATION_ERROR_00709, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)"},
+    {VALIDATION_ERROR_00710, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pCreateInfo must be a pointer to a valid VkImageCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)"},
+    {VALIDATION_ERROR_00711, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)"},
+    {VALIDATION_ERROR_00712, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pImage must be a pointer to a VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImage)"},
+    {VALIDATION_ERROR_00713, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00714, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If sharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00715, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'format must not be VK_FORMAT_UNDEFINED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00716, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'The width, height, and depth members of extent must all be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00717, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevels must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00718, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayers must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00719, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, imageType must be VK_IMAGE_TYPE_2D' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00720, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_1D, extent.width must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension1D, or VkImageFormatProperties::maxExtent.width (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00721, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00722, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL, or a pointer to a valid instance of VkDedicatedAllocationImageCreateInfoNV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00723, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00724, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'imageType must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00725, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00726, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00727, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00728, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00729, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00730, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'sharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00731, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'initialLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_00732, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must have been created with tiling equal to VK_IMAGE_TILING_LINEAR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00733, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'The aspectMask member of pSubresource must only have a single bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00734, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00735, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00736, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pSubresource must be a pointer to a valid VkImageSubresource structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00737, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pLayout must be a pointer to a VkSubresourceLayout structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00738, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSubresourceLayout)"},
+    {VALIDATION_ERROR_00739, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)"},
+    {VALIDATION_ERROR_00740, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayer must be less than the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)"},
+    {VALIDATION_ERROR_00741, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)"},
+    {VALIDATION_ERROR_00742, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresource)"},
+    {VALIDATION_ERROR_00743, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'All submitted commands that refer to image, either directly or via a VkImageView, must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00744, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If VkAllocationCallbacks were provided when image was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00745, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If no VkAllocationCallbacks were provided when image was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00746, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00747, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If image is not VK_NULL_HANDLE, image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00748, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00749, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If image is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImage)"},
+    {VALIDATION_ERROR_00750, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)"},
+    {VALIDATION_ERROR_00751, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pCreateInfo must be a pointer to a valid VkImageViewCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)"},
+    {VALIDATION_ERROR_00752, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)"},
+    {VALIDATION_ERROR_00753, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pView must be a pointer to a VkImageView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateImageView)"},
+    {VALIDATION_ERROR_00754, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was not created with VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT then viewType must not be VK_IMAGE_VIEW_TYPE_CUBE or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00755, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the image cubemap arrays feature is not enabled, viewType must not be VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00756, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the ETC2 texture compression feature is not enabled, format must not be VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or VK_FORMAT_EAC_R11G11_SNORM_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00757, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the ASTC LDR texture compression feature is not enabled, format must not be VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or VK_FORMAT_ASTC_12x12_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00758, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If the BC texture compression feature is not enabled, format must not be VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, or VK_FORMAT_BC7_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00759, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR, format must be format that has at least one supported feature bit present in the value of VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00760, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'sType must be VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00761, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00762, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00763, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00764, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'viewType must be a valid VkImageViewType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00765, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00766, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'components must be a valid VkComponentMapping structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00767, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subresourceRange must be a valid VkImageSubresourceRange structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_00768, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If levelCount is not VK_REMAINING_MIP_LEVELS, (baseMipLevel + levelCount) must be less than or equal to the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)"},
+    {VALIDATION_ERROR_00769, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If layerCount is not VK_REMAINING_ARRAY_LAYERS, (baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)"},
+    {VALIDATION_ERROR_00770, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)"},
+    {VALIDATION_ERROR_00771, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageAspectFlagBits)"},
+    {VALIDATION_ERROR_00772, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'r must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)"},
+    {VALIDATION_ERROR_00773, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'g must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)"},
+    {VALIDATION_ERROR_00774, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'b must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)"},
+    {VALIDATION_ERROR_00775, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'a must be a valid VkComponentSwizzle value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-identity-mappings)"},
+    {VALIDATION_ERROR_00776, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'All submitted commands that refer to imageView must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00777, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If VkAllocationCallbacks were provided when imageView was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00778, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If no VkAllocationCallbacks were provided when imageView was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00779, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00780, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If imageView is not VK_NULL_HANDLE, imageView must be a valid VkImageView handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00781, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00782, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If imageView is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyImageView)"},
+    {VALIDATION_ERROR_00783, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)"},
+    {VALIDATION_ERROR_00784, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)"},
+    {VALIDATION_ERROR_00785, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'pMemoryRequirements must be a pointer to a VkMemoryRequirements structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)"},
+    {VALIDATION_ERROR_00786, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetBufferMemoryRequirements)"},
+    {VALIDATION_ERROR_00787, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)"},
+    {VALIDATION_ERROR_00788, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)"},
+    {VALIDATION_ERROR_00789, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'pMemoryRequirements must be a pointer to a VkMemoryRequirements structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)"},
+    {VALIDATION_ERROR_00790, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageMemoryRequirements)"},
+    {VALIDATION_ERROR_00791, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must not already be backed by a memory object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00792, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must not have been created with any sparse memory binding flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00793, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00794, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minTexelBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00795, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00796, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with the VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, memoryOffset must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00797, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00798, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00799, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00800, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00801, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'buffer must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00802, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_00803, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must not already be backed by a memory object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00804, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must not have been created with any sparse memory binding flags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00805, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00806, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been allocated using one of the memory types allowed in the memoryTypeBits member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00807, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00808, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00809, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00810, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00811, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_00812, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)"},
+    {VALIDATION_ERROR_00813, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pCreateInfo must be a pointer to a valid VkSamplerCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)"},
+    {VALIDATION_ERROR_00814, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)"},
+    {VALIDATION_ERROR_00815, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pSampler must be a pointer to a VkSampler handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSampler)"},
+    {VALIDATION_ERROR_00816, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'The absolute value of mipLodBias must be less than or equal to VkPhysicalDeviceLimits::maxSamplerLodBias' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00817, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If the anisotropic sampling feature is not enabled, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00818, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If anisotropyEnable is VK_TRUE, maxAnisotropy must be between 1.0 and VkPhysicalDeviceLimits::maxSamplerAnisotropy, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00819, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, minFilter and magFilter must be equal' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00820, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, mipmapMode must be VK_SAMPLER_MIPMAP_MODE_NEAREST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00821, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, minLod and maxLod must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00822, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, addressModeU and addressModeV must each be either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00823, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00824, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If unnormalizedCoordinates is VK_TRUE, compareEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00825, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If any of addressModeU, addressModeV or addressModeW are VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, borderColor must be a valid VkBorderColor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00826, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If the VK_KHR_sampler_mirror_clamp_to_edge extension is not enabled, addressModeU, addressModeV and addressModeW must not be VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00827, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If compareEnable is VK_TRUE, compareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00828, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'sType must be VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00829, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00830, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00831, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'magFilter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00832, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'minFilter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00833, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'mipmapMode must be a valid VkSamplerMipmapMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00834, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeU must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00835, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeV must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00836, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'addressModeW must be a valid VkSamplerAddressMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_00837, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'All submitted commands that refer to sampler must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00838, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If VkAllocationCallbacks were provided when sampler was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00839, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If no VkAllocationCallbacks were provided when sampler was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00840, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00841, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If sampler is not VK_NULL_HANDLE, sampler must be a valid VkSampler handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00842, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00843, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If sampler is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySampler)"},
+    {VALIDATION_ERROR_00844, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00845, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pCreateInfo must be a pointer to a valid VkDescriptorSetLayoutCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00846, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00847, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pSetLayout must be a pointer to a VkDescriptorSetLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00848, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00849, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00850, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00851, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If bindingCount is not 0, pBindings must be a pointer to an array of bindingCount valid VkDescriptorSetLayoutBinding structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00852, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and descriptorCount is not 0 and pImmutableSamplers is not NULL, pImmutableSamplers must be a pointer to an array of descriptorCount valid VkSampler handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)"},
+    {VALIDATION_ERROR_00853, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorCount is not 0, stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)"},
+    {VALIDATION_ERROR_00854, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'descriptorType must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutBinding)"},
+    {VALIDATION_ERROR_00855, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If VkAllocationCallbacks were provided when descriptorSetLayout was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00856, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If no VkAllocationCallbacks were provided when descriptorSetLayout was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00857, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00858, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorSetLayout is not VK_NULL_HANDLE, descriptorSetLayout must be a valid VkDescriptorSetLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00859, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00860, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'If descriptorSetLayout is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorSetLayout)"},
+    {VALIDATION_ERROR_00861, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)"},
+    {VALIDATION_ERROR_00862, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pCreateInfo must be a pointer to a valid VkPipelineLayoutCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)"},
+    {VALIDATION_ERROR_00863, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)"},
+    {VALIDATION_ERROR_00864, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pPipelineLayout must be a pointer to a VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreatePipelineLayout)"},
+    {VALIDATION_ERROR_00865, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'setLayoutCount must be less than or equal to VkPhysicalDeviceLimits::maxBoundDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00866, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_SAMPLER and VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSamplers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00867, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorUniformBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00868, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00869, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorSampledImages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00870, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'The total number of descriptors of the type VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any given shader stage across all elements of pSetLayouts must be less than or equal to VkPhysicalDeviceLimits::maxPerStageDescriptorStorageImages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00871, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'Any two elements of pPushConstantRanges must not include the same stage in stageFlags' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00872, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00873, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00874, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00875, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If setLayoutCount is not 0, pSetLayouts must be a pointer to an array of setLayoutCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00876, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pushConstantRangeCount is not 0, pPushConstantRanges must be a pointer to an array of pushConstantRangeCount valid VkPushConstantRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineLayoutCreateInfo)"},
+    {VALIDATION_ERROR_00877, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00878, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00879, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00880, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'size must be less than or equal to VkPhysicalDeviceLimits::maxPushConstantsSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00881, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00882, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'stageFlags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPushConstantRange)"},
+    {VALIDATION_ERROR_00883, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If VkAllocationCallbacks were provided when pipelineLayout was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00884, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If no VkAllocationCallbacks were provided when pipelineLayout was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00885, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00886, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pipelineLayout is not VK_NULL_HANDLE, pipelineLayout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00887, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00888, "For more information refer to Vulkan Spec Section '13.2.2. Pipeline Layouts' which states 'If pipelineLayout is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyPipelineLayout)"},
+    {VALIDATION_ERROR_00889, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)"},
+    {VALIDATION_ERROR_00890, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pCreateInfo must be a pointer to a valid VkDescriptorPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)"},
+    {VALIDATION_ERROR_00891, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)"},
+    {VALIDATION_ERROR_00892, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorPool must be a pointer to a VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDescriptorPool)"},
+    {VALIDATION_ERROR_00893, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'maxSets must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00894, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00895, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00896, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'flags must be a valid combination of VkDescriptorPoolCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00897, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pPoolSizes must be a pointer to an array of poolSizeCount valid VkDescriptorPoolSize structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00898, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'poolSizeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolCreateFlagBits)"},
+    {VALIDATION_ERROR_00899, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolSize)"},
+    {VALIDATION_ERROR_00900, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'type must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorPoolSize)"},
+    {VALIDATION_ERROR_00901, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All submitted commands that refer to descriptorPool (via any allocated descriptor sets) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00902, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If VkAllocationCallbacks were provided when descriptorPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00903, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If no VkAllocationCallbacks were provided when descriptorPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00904, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00905, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If descriptorPool is not VK_NULL_HANDLE, descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00906, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00907, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'If descriptorPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDescriptorPool)"},
+    {VALIDATION_ERROR_00908, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)"},
+    {VALIDATION_ERROR_00909, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pAllocateInfo must be a pointer to a valid VkDescriptorSetAllocateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)"},
+    {VALIDATION_ERROR_00910, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorSets must be a pointer to an array of pAllocateInfo::descriptorSetCount VkDescriptorSet handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAllocateDescriptorSets)"},
+    {VALIDATION_ERROR_00911, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must not be greater than the number of sets that are currently available for allocation in descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00912, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have enough free descriptor capacity remaining to allocate the descriptor sets of the specified layouts' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00913, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'sType must be VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00914, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00915, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00916, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pSetLayouts must be a pointer to an array of descriptorSetCount valid VkDescriptorSetLayout handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00917, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00918, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Both of descriptorPool, and the elements of pSetLayouts must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetAllocateInfo)"},
+    {VALIDATION_ERROR_00919, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All submitted commands that refer to any element of pDescriptorSets must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00920, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'pDescriptorSets must be a pointer to an array of descriptorSetCount VkDescriptorSet handles, each element of which must either be a valid handle or VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00921, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Each valid handle in pDescriptorSets must have been allocated from descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00922, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created with the VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00923, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00924, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00925, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00926, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00927, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'Each element of pDescriptorSets that is a valid handle must have been created, allocated, or retrieved from descriptorPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkFreeDescriptorSets)"},
+    {VALIDATION_ERROR_00928, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'All uses of descriptorPool (via any allocated descriptor sets) must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)"},
+    {VALIDATION_ERROR_00929, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)"},
+    {VALIDATION_ERROR_00930, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must be a valid VkDescriptorPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)"},
+    {VALIDATION_ERROR_00931, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)"},
+    {VALIDATION_ERROR_00932, "For more information refer to Vulkan Spec Section '13.2.3. Allocation of Descriptor Sets' which states 'descriptorPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkResetDescriptorPool)"},
+    {VALIDATION_ERROR_00933, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)"},
+    {VALIDATION_ERROR_00934, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorWriteCount is not 0, pDescriptorWrites must be a pointer to an array of descriptorWriteCount valid VkWriteDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)"},
+    {VALIDATION_ERROR_00935, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorCopyCount is not 0, pDescriptorCopies must be a pointer to an array of descriptorCopyCount valid VkCopyDescriptorSet structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkUpdateDescriptorSets)"},
+    {VALIDATION_ERROR_00936, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding point within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00937, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must match the type of dstBinding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00938, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00939, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pImageInfo must be a pointer to an array of descriptorCount valid VkDescriptorImageInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00940, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pTexelBufferView must be a pointer to an array of descriptorCount valid VkBufferView handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00941, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pBufferInfo must be a pointer to an array of descriptorCount valid VkDescriptorBufferInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00942, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_SAMPLER or VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and dstSet was not allocated with a layout that included immutable samplers for dstBinding with descriptorType, the sampler member of any given element of pImageInfo must be a valid VkSampler object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00943, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView and imageLayout members of any given element of pImageInfo must be a valid VkImageView and VkImageLayout, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00944, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minUniformBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00945, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the offset member of any given element of pBufferInfo must be a multiple of VkPhysicalDeviceLimits::minStorageBufferOffsetAlignment' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00946, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00947, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the buffer member of any given element of pBufferInfo must have been created with VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00948, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxUniformBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00949, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the range member of any given element of pBufferInfo, or the effective range if range is VK_WHOLE_SIZE, must be less than or equal to VkPhysicalDeviceLimits::maxStorageBufferRange' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00950, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00951, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the VkBuffer that any given element of pTexelBufferView was created from must have been created with VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00952, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If descriptorType is VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the imageView member of any given element of pImageInfo must have been created with the identity swizzle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00953, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00954, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00955, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00956, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorType must be a valid VkDescriptorType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00957, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'descriptorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00958, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of dstSet, and the elements of pTexelBufferView that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#descriptorsets-updates-consecutive)"},
+    {VALIDATION_ERROR_00959, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)"},
+    {VALIDATION_ERROR_00960, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)"},
+    {VALIDATION_ERROR_00961, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If range is not equal to VK_WHOLE_SIZE, range must be less than or equal to the size of buffer minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)"},
+    {VALIDATION_ERROR_00962, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorBufferInfo)"},
+    {VALIDATION_ERROR_00963, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of imageView, and sampler that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorImageInfo)"},
+    {VALIDATION_ERROR_00964, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcBinding must be a valid binding within srcSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00965, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of srcArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by srcBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00966, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstBinding must be a valid binding within dstSet' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00967, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00968, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'If srcSet is equal to dstSet, then the source and destination ranges of descriptors must not overlap, where the ranges may include array elements from consecutive bindings as described by consecutive binding updates' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00969, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'sType must be VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00970, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00971, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'srcSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00972, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'dstSet must be a valid VkDescriptorSet handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00973, "For more information refer to Vulkan Spec Section '13.2.4. Descriptor Set Updates' which states 'Both of dstSet, and srcSet must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkCopyDescriptorSet)"},
+    {VALIDATION_ERROR_00974, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Any given element of pDescriptorSets must have been allocated with a VkDescriptorSetLayout that matches (is the same as, or defined identically to) the VkDescriptorSetLayout at set n in layout, where n is the sum of firstSet and the index into pDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00975, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'dynamicOffsetCount must be equal to the total number of dynamic descriptors in pDescriptorSets' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00976, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'The sum of firstSet and descriptorSetCount must be less than or equal to VkPipelineLayoutCreateInfo::setLayoutCount provided when layout was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00977, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pipelineBindPoint must be supported by the commandBuffers parent VkCommandPools queue family' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00978, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Any given element of pDynamicOffsets must satisfy the required alignment for the corresponding descriptor bindings descriptor type' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00979, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00980, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pipelineBindPoint must be a valid VkPipelineBindPoint value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00981, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00982, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'pDescriptorSets must be a pointer to an array of descriptorSetCount valid VkDescriptorSet handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00983, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'If dynamicOffsetCount is not 0, pDynamicOffsets must be a pointer to an array of dynamicOffsetCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00984, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00985, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00986, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'descriptorSetCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00987, "For more information refer to Vulkan Spec Section '13.2.5. Descriptor Set Binding' which states 'Each of commandBuffer, layout, and the elements of pDescriptorSets must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindDescriptorSets)"},
+    {VALIDATION_ERROR_00988, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must match exactly the shader stages used in layout for the range specified by offset and size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00989, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00990, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00991, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'offset must be less than VkPhysicalDeviceLimits::maxPushConstantsSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00992, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be less than or equal to VkPhysicalDeviceLimits::maxPushConstantsSize minus offset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00993, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00994, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'layout must be a valid VkPipelineLayout handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00995, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must be a valid combination of VkShaderStageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00996, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'stageFlags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00997, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'pValues must be a pointer to an array of size bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00998, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_00999, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_01000, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_01001, "For more information refer to Vulkan Spec Section '13.2.6. Push Constant Updates' which states 'Both of commandBuffer, and layout must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPushConstants)"},
+    {VALIDATION_ERROR_01002, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)"},
+    {VALIDATION_ERROR_01003, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pCreateInfo must be a pointer to a valid VkQueryPoolCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)"},
+    {VALIDATION_ERROR_01004, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)"},
+    {VALIDATION_ERROR_01005, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pQueryPool must be a pointer to a VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateQueryPool)"},
+    {VALIDATION_ERROR_01006, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If the pipeline statistics queries feature is not enabled, queryType must not be VK_QUERY_TYPE_PIPELINE_STATISTICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01007, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryType is VK_QUERY_TYPE_PIPELINE_STATISTICS, pipelineStatistics must be a valid combination of VkQueryPipelineStatisticFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01008, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'sType must be VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01009, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01010, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01011, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'queryType must be a valid VkQueryType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkQueryType)"},
+    {VALIDATION_ERROR_01012, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'All submitted commands that refer to queryPool must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01013, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If VkAllocationCallbacks were provided when queryPool was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01014, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If no VkAllocationCallbacks were provided when queryPool was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01015, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01016, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryPool is not VK_NULL_HANDLE, queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01017, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01018, "For more information refer to Vulkan Spec Section '16.1. Query Pools' which states 'If queryPool is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyQueryPool)"},
+    {VALIDATION_ERROR_01019, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01020, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01021, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01022, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01023, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01024, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01025, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01026, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResetQueryPool)"},
+    {VALIDATION_ERROR_01027, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must currently not be active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01028, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must be unavailable' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01029, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the precise occlusion queries feature is not enabled, or the queryType used to create queryPool was not VK_QUERY_TYPE_OCCLUSION, flags must not contain VK_QUERY_CONTROL_PRECISE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01030, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must have been created with a queryType that differs from that of any other queries that have been made active, and are currently still active within commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01031, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'query must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01032, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_OCCLUSION, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01033, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate graphics operations, the VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01034, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pipelineStatistics indicate compute operations, the VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01035, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01036, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01037, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryControlFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01038, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01039, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01040, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-active)"},
+    {VALIDATION_ERROR_01041, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The query identified by queryPool and query must currently be active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01042, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'query must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01043, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01044, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01045, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01046, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01047, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-operation-finished)"},
+    {VALIDATION_ERROR_01048, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01049, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is not set in flags then pData and stride must be multiples of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01050, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is set in flags then pData and stride must be multiples of 8' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01051, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01052, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dataSize must be large enough to contain the result of each query, as described here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01053, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01054, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01055, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01056, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01057, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryResultFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01058, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dataSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01059, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#queries-wait-bit-not-set)"},
+    {VALIDATION_ERROR_01060, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01061, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'firstQuery must be less than the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01062, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The sum of firstQuery and queryCount must be less than or equal to the number of queries in queryPool' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01063, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is not set in flags then dstOffset and stride must be multiples of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01064, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If VK_QUERY_RESULT_64_BIT is set in flags then dstOffset and stride must be multiples of 8' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01065, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must have enough storage, from dstOffset, to contain the result of each query, as described here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01066, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01067, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'If the queryType used to create queryPool was VK_QUERY_TYPE_TIMESTAMP, flags must not contain VK_QUERY_RESULT_PARTIAL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01068, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01069, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01070, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01071, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'flags must be a valid combination of VkQueryResultFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01072, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01073, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01074, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01075, "For more information refer to Vulkan Spec Section '16.2. Query Operation' which states 'Each of commandBuffer, dstBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyQueryPoolResults)"},
+    {VALIDATION_ERROR_01076, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The query identified by queryPool and query must be unavailable' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01077, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The command pools queue family must support a non-zero timestampValidBits' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01078, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01079, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'pipelineStage must be a valid VkPipelineStageFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01080, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'queryPool must be a valid VkQueryPool handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01081, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01082, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01083, "For more information refer to Vulkan Spec Section '16.5. Timestamp Queries' which states 'Both of commandBuffer, and queryPool must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWriteTimestamp)"},
+    {VALIDATION_ERROR_01084, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01085, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must specify the layout of the image subresource ranges of image specified in pRanges at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01086, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01087, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The image range of any given element of pRanges must be an image subresource range that is contained within image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01088, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must not have a compressed or depth/stencil format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01089, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01090, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01091, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01092, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pColor must be a pointer to a valid VkClearColorValue union' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01093, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pRanges must be a pointer to an array of rangeCount valid VkImageSubresourceRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01094, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01095, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01096, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01097, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'rangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01098, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'Both of commandBuffer, and image must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearColorImage)"},
+    {VALIDATION_ERROR_01099, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01100, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must specify the layout of the image subresource ranges of image specified in pRanges at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01101, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01102, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The image range of any given element of pRanges must be an image subresource range that is contained within image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01103, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must have a depth/stencil format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01104, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01105, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01106, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'imageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01107, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pDepthStencil must be a pointer to a valid VkClearDepthStencilValue structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01108, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'pRanges must be a pointer to an array of rangeCount valid VkImageSubresourceRange structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01109, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01110, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01111, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01112, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'rangeCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01113, "For more information refer to Vulkan Spec Section '17.1. Clearing Images Outside A Render Pass Instance' which states 'Both of commandBuffer, and image must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearDepthStencilImage)"},
+    {VALIDATION_ERROR_01114, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'If the aspectMask member of any given element of pAttachments contains VK_IMAGE_ASPECT_COLOR_BIT, the colorAttachment member of those elements must refer to a valid color attachment in the current subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01115, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The rectangular region specified by a given element of pRects must be contained within the render area of the current render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01116, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The layers specified by a given element of pRects must be contained within every attachment that pAttachments refers to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01117, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01118, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'pAttachments must be a pointer to an array of attachmentCount valid VkClearAttachment structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01119, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'pRects must be a pointer to an array of rectCount VkClearRect structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01120, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01121, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01122, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01123, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'attachmentCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01124, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'rectCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdClearAttachments)"},
+    {VALIDATION_ERROR_01125, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'If aspectMask includes VK_IMAGE_ASPECT_COLOR_BIT, it must not include VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)"},
+    {VALIDATION_ERROR_01126, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must not include VK_IMAGE_ASPECT_METADATA_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)"},
+    {VALIDATION_ERROR_01127, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)"},
+    {VALIDATION_ERROR_01128, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)"},
+    {VALIDATION_ERROR_01129, "For more information refer to Vulkan Spec Section '17.2. Clearing Images Inside A Render Pass Instance' which states 'clearValue must be a valid VkClearValue union' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearAttachment)"},
+    {VALIDATION_ERROR_01130, "For more information refer to Vulkan Spec Section '17.3. Clear Values' which states 'depth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearDepthStencilValue)"},
+    {VALIDATION_ERROR_01131, "For more information refer to Vulkan Spec Section '17.3. Clear Values' which states 'depthStencil must be a valid VkClearDepthStencilValue structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkClearValue)"},
+    {VALIDATION_ERROR_01132, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01133, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01134, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01135, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01136, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'If size is not equal to VK_WHOLE_SIZE, size must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01137, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01138, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01139, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01140, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01141, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01142, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01143, "For more information refer to Vulkan Spec Section '17.4. Filling Buffers' which states 'Both of commandBuffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdFillBuffer)"},
+    {VALIDATION_ERROR_01144, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstOffset must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01145, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01146, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01147, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01148, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be less than or equal to 65536' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01149, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01150, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01151, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01152, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'pData must be a pointer to an array of dataSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01153, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01154, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01155, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01156, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'dataSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01157, "For more information refer to Vulkan Spec Section '17.5. Updating Buffers' which states 'Both of commandBuffer, and dstBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdUpdateBuffer)"},
+    {VALIDATION_ERROR_01158, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01159, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The srcOffset member of a given element of pRegions must be less than the size of srcBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01160, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The dstOffset member of a given element of pRegions must be less than the size of dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01161, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be less than or equal to the size of srcBuffer minus srcOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01162, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The size member of a given element of pRegions must be less than or equal to the size of dstBuffer minus dstOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01163, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The union of the source regions, and the union of the destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01164, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01165, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01166, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01167, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'srcBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01168, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01169, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'pRegions must be a pointer to an array of regionCount VkBufferCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01170, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01171, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01172, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01173, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01174, "For more information refer to Vulkan Spec Section '18.2. Copying Data Between Buffers' which states 'Each of commandBuffer, dstBuffer, and srcBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBuffer)"},
+    {VALIDATION_ERROR_01175, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01176, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01177, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01178, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01179, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01180, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01181, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01182, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01183, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01184, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The VkFormat of each of srcImage and dstImage must be compatible, as defined below' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01185, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The sample count of srcImage and dstImage must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01186, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01187, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01188, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01189, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01190, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01191, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'pRegions must be a pointer to an array of regionCount valid VkImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01192, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01193, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01194, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01195, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01196, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#copies-images-format-compatibility)"},
+    {VALIDATION_ERROR_01197, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01198, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01199, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01200, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of srcSubresource must specify aspects present in the calling commands srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01201, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'The aspectMask member of dstSubresource must specify aspects present in the calling commands dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01202, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.x and (extent.width + srcOffset.x) must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01203, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.y and (extent.height + srcOffset.y) must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01204, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset.z and (extent.depth + srcOffset.z) must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01205, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.x and (extent.width + dstOffset.x) must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01206, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.y and (extent.height + dstOffset.y) must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01207, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstOffset.z and (extent.depth + dstOffset.z) must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01208, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is a compressed format image:all members of srcOffset must be a multiple of the corresponding dimensions of the compressed texel blockextent.width must be a multiple of the compressed texel block width or (extent.width + srcOffset.x) must equal the source image subresource widthextent.height must be a multiple of the compressed texel block height or (extent.height + srcOffset.y) must equal the source image subresource heightextent.depth must be a multiple of the compressed texel block depth or (extent.depth + srcOffset.z) must equal the source image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01209, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'all members of srcOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01210, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.width must be a multiple of the compressed texel block width or (extent.width + srcOffset.x) must equal the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01211, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.height must be a multiple of the compressed texel block height or (extent.height + srcOffset.y) must equal the source image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01212, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.depth must be a multiple of the compressed texel block depth or (extent.depth + srcOffset.z) must equal the source image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01213, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is a compressed format image:all members of dstOffset must be a multiple of the corresponding dimensions of the compressed texel blockextent.width must be a multiple of the compressed texel block width or (extent.width + dstOffset.x) must equal the destination image subresource widthextent.height must be a multiple of the compressed texel block height or (extent.height + dstOffset.y) must equal the destination image subresource heightextent.depth must be a multiple of the compressed texel block depth or (extent.depth + dstOffset.z) must equal the destination image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01214, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'all members of dstOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01215, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.width must be a multiple of the compressed texel block width or (extent.width + dstOffset.x) must equal the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01216, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.height must be a multiple of the compressed texel block height or (extent.height + dstOffset.y) must equal the destination image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01217, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'extent.depth must be a multiple of the compressed texel block depth or (extent.depth + dstOffset.z) must equal the destination image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01218, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcOffset, dstOffset, and extent must respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in Physical Device Enumeration' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01219, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01220, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01221, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If aspectMask contains VK_IMAGE_ASPECT_COLOR_BIT, it must not contain either of VK_IMAGE_ASPECT_DEPTH_BIT or VK_IMAGE_ASPECT_STENCIL_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01222, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must not contain VK_IMAGE_ASPECT_METADATA_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01223, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'mipLevel must be less than the mipLevels specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01224, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states '(baseArrayLayer + layerCount) must be less than or equal to the arrayLayers specified in VkImageCreateInfo when the image was created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01225, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must be a valid combination of VkImageAspectFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01226, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'aspectMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageSubresourceLayers)"},
+    {VALIDATION_ERROR_01227, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The buffer region specified by a given element of pRegions must be a region that is contained within srcBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01228, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The image region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01229, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01230, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01231, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01232, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01233, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01234, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01235, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01236, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01237, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01238, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01239, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'pRegions must be a pointer to an array of regionCount valid VkBufferImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01240, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01241, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01242, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01243, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01244, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'Each of commandBuffer, dstImage, and srcBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyBufferToImage)"},
+    {VALIDATION_ERROR_01245, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The image region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01246, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The buffer region specified by a given element of pRegions must be a region that is contained within dstBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01247, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01248, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01249, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01250, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01251, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01252, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstBuffer must have been created with VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01253, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01254, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01255, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01256, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'dstBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01257, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'pRegions must be a pointer to an array of regionCount valid VkBufferImageCopy structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01258, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01259, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The VkCommandPool that commandBuffer was allocated from must support transfer, graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01260, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01261, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01262, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'Each of commandBuffer, dstBuffer, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdCopyImageToBuffer)"},
+    {VALIDATION_ERROR_01263, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of the calling commands VkImage parameters formats element size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01264, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01265, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferRowLength must be 0, or greater than or equal to the width member of imageExtent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01266, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferImageHeight must be 0, or greater than or equal to the height member of imageExtent' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01267, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.x and (imageExtent.width + imageOffset.x) must both be greater than or equal to 0 and less than or equal to the image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01268, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.y and (imageExtent.height + imageOffset.y) must both be greater than or equal to 0 and less than or equal to the image subresource heightIf the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D, then imageOffset.y must be 0 and imageExtent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01269, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageOffset.z and (imageExtent.depth + imageOffset.z) must both be greater than or equal to 0 and less than or equal to the image subresource depthIf the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then imageOffset.z must be 0 and imageExtent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01270, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands VkImage parameter is a compressed format image:bufferRowLength must be a multiple of the compressed texel block widthbufferImageHeight must be a multiple of the compressed texel block heightall members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel blockbufferOffset must be a multiple of the compressed texel block size in bytesimageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) must equal the image subresource widthimageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) must equal the image subresource heightimageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) must equal the image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01271, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferRowLength must be a multiple of the compressed texel block width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01272, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferImageHeight must be a multiple of the compressed texel block height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01273, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'all members of imageOffset must be a multiple of the corresponding dimensions of the compressed texel block' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01274, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset must be a multiple of the compressed texel block size in bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01275, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.width must be a multiple of the compressed texel block width or (imageExtent.width + imageOffset.x) must equal the image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01276, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.height must be a multiple of the compressed texel block height or (imageExtent.height + imageOffset.y) must equal the image subresource height' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01277, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageExtent.depth must be a multiple of the compressed texel block depth or (imageExtent.depth + imageOffset.z) must equal the image subresource depth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01278, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'bufferOffset, bufferRowLength, bufferImageHeight and all members of imageOffset and imageExtent must respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in Physical Device Enumeration' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01279, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The aspectMask member of imageSubresource must specify aspects present in the calling commands VkImage parameter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01280, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'The aspectMask member of imageSubresource must only have a single bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01281, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands VkImage parameter is of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of imageSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01282, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'When copying to the depth aspect of an image subresource, the data in the source buffer must be in the range [0,1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01283, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'imageSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01287, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01288, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01289, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The union of all destination regions, specified by the elements of pRegions, must not overlap in memory with any texel that may be sampled during the blit operation' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01290, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must use a format that supports VK_FORMAT_FEATURE_BLIT_SRC_BIT, which is indicated by VkFormatProperties::linearTilingFeatures (for linear tiled images) or VkFormatProperties::optimalTilingFeatures (for optimally tiled images) - as returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01291, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01292, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01293, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01294, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01295, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01296, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'pRegions must be a pointer to an array of regionCount valid VkImageBlit structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01297, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'filter must be a valid VkFilter value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01298, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01299, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01300, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01301, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01302, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_01303, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01304, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01305, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01306, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of srcSubresource must specify aspects present in the calling commands srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01307, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The aspectMask member of dstSubresource must specify aspects present in the calling commands dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01308, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The layerCount member of dstSubresource must be equal to the layerCount member of srcSubresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01309, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].x and srcOffset[1].x must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01310, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].y and srcOffset[1].y must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset[0].y must be 0 and srcOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01311, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcOffset[0].z and srcOffset[1].z must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01312, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].x and dstOffset[1].x must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01313, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].y and dstOffset[1].y must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset[0].y must be 0 and dstOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01314, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstOffset[0].z and dstOffset[1].z must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01315, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01316, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01317, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The source region specified by a given element of pRegions must be a region that is contained within srcImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01318, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The destination region specified by a given element of pRegions must be a region that is contained within dstImage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01319, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The union of all source regions, and the union of all destination regions, specified by the elements of pRegions, must not overlap in memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01320, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImage must have a sample count equal to any valid sample count value other than VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01321, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImage must have a sample count equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01322, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01323, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01324, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01325, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01326, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If dstImage was created with tiling equal to VK_IMAGE_TILING_LINEAR, dstImage must have been created with a format that supports being a color attachment, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01327, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01328, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01329, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01330, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImage must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01331, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstImageLayout must be a valid VkImageLayout value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01332, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'pRegions must be a pointer to an array of regionCount valid VkImageResolve structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01333, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01334, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01335, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01336, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'regionCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01337, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'Each of commandBuffer, dstImage, and srcImage must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_01338, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The aspectMask member of srcSubresource and dstSubresource must only contain VK_IMAGE_ASPECT_COLOR_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01339, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'The layerCount member of srcSubresource and dstSubresource must match' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01340, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If either of the calling commands srcImage or dstImage parameters are of VkImageType VK_IMAGE_TYPE_3D, the baseArrayLayer and layerCount members of both srcSubresource and dstSubresource must be 0 and 1, respectively' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01341, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01342, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstSubresource must be a valid VkImageSubresourceLayers structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01343, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, primitiveRestartEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01344, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the geometry shaders feature is not enabled, topology must not be any of VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01345, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the tessellation shaders feature is not enabled, topology must not be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01346, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01347, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01348, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01349, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'topology must be a valid VkPrimitiveTopology value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineInputAssemblyStateCreateInfo)"},
+    {VALIDATION_ERROR_01350, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be less than the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01351, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The sum of offset and the address of the range of VkDeviceMemory object that is backing buffer, must be a multiple of the type indicated by indexType' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01352, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must have been created with the VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01353, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01354, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01355, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'indexType must be a valid VkIndexType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01356, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01357, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01358, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkIndexType)"},
+    {VALIDATION_ERROR_01359, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01360, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01361, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01362, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01363, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01364, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01365, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01366, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01367, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01368, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01369, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01370, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01371, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01372, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01373, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01374, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01375, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the multi-draw indirect feature is not enabled, drawCount must be 0 or 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01376, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01377, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01378, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01379, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01380, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01381, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01382, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_01383, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndirectCommand)"},
+    {VALIDATION_ERROR_01384, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndirectCommand)"},
+    {VALIDATION_ERROR_01385, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01386, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndexedIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01387, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the multi-draw indirect feature is not enabled, drawCount must be 0 or 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01388, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01389, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01390, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01391, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01392, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01393, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01394, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_01395, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)"},
+    {VALIDATION_ERROR_01396, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states '(indexSize * (firstIndex + indexCount) + offset) must be less than or equal to the size of the currently bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexType, and offset are specified via vkCmdBindIndexBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)"},
+    {VALIDATION_ERROR_01397, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'vertexBindingDescriptionCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01398, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'vertexAttributeDescriptionCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01399, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'For every binding specified by any given element of pVertexAttributeDescriptions, a VkVertexInputBindingDescription must exist in pVertexBindingDescriptions with the same value of binding' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01400, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pVertexBindingDescriptions must describe distinct binding numbers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01401, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pVertexAttributeDescriptions must describe distinct attribute locations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01402, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01403, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01404, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01405, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'If vertexBindingDescriptionCount is not 0, pVertexBindingDescriptions must be a pointer to an array of vertexBindingDescriptionCount valid VkVertexInputBindingDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01406, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'If vertexAttributeDescriptionCount is not 0, pVertexAttributeDescriptions must be a pointer to an array of vertexAttributeDescriptionCount valid VkVertexInputAttributeDescription structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineVertexInputStateCreateInfo)"},
+    {VALIDATION_ERROR_01407, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)"},
+    {VALIDATION_ERROR_01408, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'stride must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindingStride' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)"},
+    {VALIDATION_ERROR_01409, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'inputRate must be a valid VkVertexInputRate value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputRate)"},
+    {VALIDATION_ERROR_01410, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'location must be less than VkPhysicalDeviceLimits::maxVertexInputAttributes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)"},
+    {VALIDATION_ERROR_01411, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'binding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)"},
+    {VALIDATION_ERROR_01412, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'offset must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputAttributeOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)"},
+    {VALIDATION_ERROR_01413, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'format must be allowed as a vertex buffer format, as specified by the VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)"},
+    {VALIDATION_ERROR_01414, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkVertexInputAttributeDescription)"},
+    {VALIDATION_ERROR_01415, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'firstBinding must be less than VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01416, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'The sum of firstBinding and bindingCount must be less than or equal to VkPhysicalDeviceLimits::maxVertexInputBindings' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01417, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pOffsets must be less than the size of the corresponding element in pBuffers' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01418, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'All elements of pBuffers must have been created with the VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01419, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01420, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pBuffers must be a pointer to an array of bindingCount valid VkBuffer handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01421, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'pOffsets must be a pointer to an array of bindingCount VkDeviceSize values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01422, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01423, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01424, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'bindingCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01425, "For more information refer to Vulkan Spec Section '20.2. Vertex Input Description' which states 'Both of commandBuffer, and the elements of pBuffers must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBindVertexBuffers)"},
+    {VALIDATION_ERROR_01426, "For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'patchControlPoints must be greater than zero and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)"},
+    {VALIDATION_ERROR_01427, "For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)"},
+    {VALIDATION_ERROR_01428, "For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)"},
+    {VALIDATION_ERROR_01429, "For more information refer to Vulkan Spec Section '21.7. Tessellation Pipeline State' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineTessellationStateCreateInfo)"},
+    {VALIDATION_ERROR_01430, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the multiple viewports feature is not enabled, viewportCount must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01431, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the multiple viewports feature is not enabled, scissorCount must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01432, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01433, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01434, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount and viewportCount must be identical' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01435, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01436, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01437, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01438, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01439, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'scissorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineViewportStateCreateInfo)"},
+    {VALIDATION_ERROR_01440, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01441, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'firstViewport must be less than VkPhysicalDeviceLimits::maxViewports' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01442, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The sum of firstViewport and viewportCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01443, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01444, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pViewports must be a pointer to an array of viewportCount valid VkViewport structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01445, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01446, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01447, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'viewportCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetViewport)"},
+    {VALIDATION_ERROR_01448, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'width must be greater than 0.0 and less than or equal to VkPhysicalDeviceLimits::maxViewportDimensions[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01449, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'height must be greater than 0.0 and less than or equal to VkPhysicalDeviceLimits::maxViewportDimensions[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01450, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'x and y must each be between viewportBoundsRange[0] and viewportBoundsRange[1], inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01451, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'x + width must be less than or equal to viewportBoundsRange[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01452, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'y + height must be less than or equal to viewportBoundsRange[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01453, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'minDepth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01454, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'maxDepth must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01455, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the depth clamping feature is not enabled, depthClampEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01456, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the non-solid fill modes feature is not enabled, polygonMode must be VK_POLYGON_MODE_FILL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01457, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01458, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL, or a pointer to a valid instance of VkPipelineRasterizationStateRasterizationOrderAMD' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01459, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01460, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'polygonMode must be a valid VkPolygonMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01461, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'cullMode must be a valid combination of VkCullModeFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01462, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'frontFace must be a valid VkFrontFace value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateCreateInfo)"},
+    {VALIDATION_ERROR_01463, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the sample rate shading feature is not enabled, sampleShadingEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01464, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the alpha to one feature is not enabled, alphaToOneEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01465, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'minSampleShading must be in the range [0,1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01466, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01467, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01468, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01469, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'rasterizationSamples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01470, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If pSampleMask is not NULL, pSampleMask must be a pointer to an array of $/lceil{/mathit{rasterizationSamples} /over 32}/rceil$ VkSampleMask values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineMultisampleStateCreateInfo)"},
+    {VALIDATION_ERROR_01476, "For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)"},
+    {VALIDATION_ERROR_01477, "For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'If the wide lines feature is not enabled, lineWidth must be 1.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)"},
+    {VALIDATION_ERROR_01478, "For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)"},
+    {VALIDATION_ERROR_01479, "For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)"},
+    {VALIDATION_ERROR_01480, "For more information refer to Vulkan Spec Section '24.6. Line Segments' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetLineWidth)"},
+    {VALIDATION_ERROR_01481, "For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)"},
+    {VALIDATION_ERROR_01482, "For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'If the depth bias clamping feature is not enabled, depthBiasClamp must be 0.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)"},
+    {VALIDATION_ERROR_01483, "For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)"},
+    {VALIDATION_ERROR_01484, "For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)"},
+    {VALIDATION_ERROR_01485, "For more information refer to Vulkan Spec Section '24.7.3. Depth Bias' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBias)"},
+    {VALIDATION_ERROR_01486, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_SCISSOR dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01487, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'firstScissor must be less than VkPhysicalDeviceLimits::maxViewports' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01488, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The sum of firstScissor and scissorCount must be between 1 and VkPhysicalDeviceLimits::maxViewports, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01489, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The x and y members of offset must be greater than or equal to 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01490, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'Evaluation of (offset.x + extent.width) must not cause a signed integer addition overflow' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01491, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'Evaluation of (offset.y + extent.height) must not cause a signed integer addition overflow' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01492, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01493, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'pScissors must be a pointer to an array of scissorCount VkRect2D structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01494, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01495, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01496, "For more information refer to Vulkan Spec Section '25.2. Scissor Test' which states 'scissorCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetScissor)"},
+    {VALIDATION_ERROR_01497, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'If the depth bounds testing feature is not enabled, depthBoundsTestEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01498, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01499, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01500, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01501, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'depthCompareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01502, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'front must be a valid VkStencilOpState structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01503, "For more information refer to Vulkan Spec Section '25.7. Depth and Stencil Operations' which states 'back must be a valid VkStencilOpState structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineDepthStencilStateCreateInfo)"},
+    {VALIDATION_ERROR_01504, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01505, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'minDepthBounds must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01506, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'maxDepthBounds must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01507, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01508, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01509, "For more information refer to Vulkan Spec Section '25.8. Depth Bounds Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetDepthBounds)"},
+    {VALIDATION_ERROR_01510, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'failOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)"},
+    {VALIDATION_ERROR_01511, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'passOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)"},
+    {VALIDATION_ERROR_01512, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'depthFailOp must be a valid VkStencilOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)"},
+    {VALIDATION_ERROR_01513, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'compareOp must be a valid VkCompareOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilOpState)"},
+    {VALIDATION_ERROR_01514, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01515, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01516, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01517, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01518, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01519, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkStencilFaceFlagBits)"},
+    {VALIDATION_ERROR_01520, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01521, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01522, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01523, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01524, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01525, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilWriteMask)"},
+    {VALIDATION_ERROR_01526, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01527, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01528, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must be a valid combination of VkStencilFaceFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01529, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'faceMask must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01530, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01531, "For more information refer to Vulkan Spec Section '25.9. Stencil Test' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetStencilReference)"},
+    {VALIDATION_ERROR_01532, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the independent blending feature is not enabled, all elements of pAttachments must be identical' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01533, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the logic operations feature is not enabled, logicOpEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01534, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01535, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01536, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01537, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01538, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If attachmentCount is not 0, pAttachments must be a pointer to an array of attachmentCount valid VkPipelineColorBlendAttachmentState structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendStateCreateInfo)"},
+    {VALIDATION_ERROR_01539, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, srcColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01540, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, dstColorBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01541, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, srcAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01542, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'If the dual source blending feature is not enabled, dstAlphaBlendFactor must not be VK_BLEND_FACTOR_SRC1_COLOR, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, VK_BLEND_FACTOR_SRC1_ALPHA, or VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01543, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'srcColorBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01544, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'dstColorBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01545, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'colorBlendOp must be a valid VkBlendOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01546, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'srcAlphaBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01547, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'dstAlphaBlendFactor must be a valid VkBlendFactor value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01548, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'alphaBlendOp must be a valid VkBlendOp value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01549, "For more information refer to Vulkan Spec Section '26.1. Blending' which states 'colorWriteMask must be a valid combination of VkColorComponentFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineColorBlendAttachmentState)"},
+    {VALIDATION_ERROR_01550, "For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'The currently bound graphics pipeline must have been created with the VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)"},
+    {VALIDATION_ERROR_01551, "For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)"},
+    {VALIDATION_ERROR_01552, "For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)"},
+    {VALIDATION_ERROR_01553, "For more information refer to Vulkan Spec Section '26.1.1. Blend Factors' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdSetBlendConstants)"},
+    {VALIDATION_ERROR_01554, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'x must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01555, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'y must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01556, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'z must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[2]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01557, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01558, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01559, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01560, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01561, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01562, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_01563, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01564, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01565, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01566, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01567, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01568, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The VkCommandPool that commandBuffer was allocated from must support compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01569, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'This command must only be called outside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01570, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Both of buffer, and commandBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_01571, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'x must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[0]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)"},
+    {VALIDATION_ERROR_01572, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'y must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[1]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)"},
+    {VALIDATION_ERROR_01573, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'z must be less than or equal to VkPhysicalDeviceLimits::maxComputeWorkGroupCount[2]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDispatchIndirectCommand)"},
+    {VALIDATION_ERROR_01600, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'samples must be a bit value that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, and usage equal to those in this command and flags equal to the value that is set in VkImageCreateInfo::flags when the image is created' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01601, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01602, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01603, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01604, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'samples must be a valid VkSampleCountFlagBits value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01605, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01606, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01607, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01608, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01609, "For more information refer to Vulkan Spec Section '28.7.3. Sparse Image Format Properties' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkSparseImageFormatProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSparseImageFormatProperties)"},
+    {VALIDATION_ERROR_01610, "For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)"},
+    {VALIDATION_ERROR_01611, "For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)"},
+    {VALIDATION_ERROR_01612, "For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'pSparseMemoryRequirementCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)"},
+    {VALIDATION_ERROR_01613, "For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'If the value referenced by pSparseMemoryRequirementCount is not 0, and pSparseMemoryRequirements is not NULL, pSparseMemoryRequirements must be a pointer to an array of pSparseMemoryRequirementCount VkSparseImageMemoryRequirements structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)"},
+    {VALIDATION_ERROR_01614, "For more information refer to Vulkan Spec Section '28.7.5. Sparse Resource Memory Requirements' which states 'image must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetImageSparseMemoryRequirements)"},
+    {VALIDATION_ERROR_01615, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory and memoryOffset must match the memory requirements of the resource, as described in section Section 11.6, Resource Memory Association' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01616, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must not have been created with a memory type that reports VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01617, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01618, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'resourceOffset must be less than the size of the resource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01619, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be less than or equal to the size of the resource minus resourceOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01620, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'memoryOffset must be less than the size of memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01621, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'size must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01622, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01623, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'flags must be a valid combination of VkSparseMemoryBindFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseMemoryBindFlagBits)"},
+    {VALIDATION_ERROR_01624, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)"},
+    {VALIDATION_ERROR_01625, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)"},
+    {VALIDATION_ERROR_01626, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseBufferMemoryBindInfo)"},
+    {VALIDATION_ERROR_01627, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'For any given element of pBinds, if the flags member of that element contains VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range defined must be within the mip tail region of the metadata aspect of image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)"},
+    {VALIDATION_ERROR_01628, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)"},
+    {VALIDATION_ERROR_01629, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)"},
+    {VALIDATION_ERROR_01630, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageOpaqueMemoryBindInfo)"},
+    {VALIDATION_ERROR_01631, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)"},
+    {VALIDATION_ERROR_01632, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pBinds must be a pointer to an array of bindCount valid VkSparseImageMemoryBind structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)"},
+    {VALIDATION_ERROR_01633, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'bindCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBindInfo)"},
+    {VALIDATION_ERROR_01634, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If the sparse aliased residency feature is not enabled, and if any other resources are bound to ranges of memory, the range of memory being bound must not overlap with those bound ranges' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01635, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'memory and memoryOffset must match the memory requirements of the calling commands image, as described in section Section 11.6, Resource Memory Association' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01636, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'subresource must be a valid image subresource for image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01637, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.x must be a multiple of the sparse image block width (VkSparseImageFormatProperties::imageGranularity.width) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01638, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.width must either be a multiple of the sparse image block width of the image, or else extent.width + offset.x must equal the width of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01639, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.y must be a multiple of the sparse image block height (VkSparseImageFormatProperties::imageGranularity.height) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01640, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.height must either be a multiple of the sparse image block height of the image, or else extent.height + offset.y must equal the height of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01641, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'offset.z must be a multiple of the sparse image block depth (VkSparseImageFormatProperties::imageGranularity.depth) of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01642, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'extent.depth must either be a multiple of the sparse image block depth of the image, or else extent.depth + offset.z must equal the depth of the image subresource' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01643, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'subresource must be a valid VkImageSubresource structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01644, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If memory is not VK_NULL_HANDLE, memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01645, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'flags must be a valid combination of VkSparseMemoryBindFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSparseImageMemoryBind)"},
+    {VALIDATION_ERROR_01646, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'fence must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01647, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'fence must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01648, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01649, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If bindInfoCount is not 0, pBindInfo must be a pointer to an array of bindInfoCount valid VkBindSparseInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01650, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01651, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'The queue must support sparse binding operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01652, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'Both of fence, and queue that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueueBindSparse)"},
+    {VALIDATION_ERROR_01653, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'sType must be VK_STRUCTURE_TYPE_BIND_SPARSE_INFO' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01654, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01655, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If waitSemaphoreCount is not 0, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01656, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If bufferBindCount is not 0, pBufferBinds must be a pointer to an array of bufferBindCount valid VkSparseBufferMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01657, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If imageOpaqueBindCount is not 0, pImageOpaqueBinds must be a pointer to an array of imageOpaqueBindCount valid VkSparseImageOpaqueMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01658, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If imageBindCount is not 0, pImageBinds must be a pointer to an array of imageBindCount valid VkSparseImageMemoryBindInfo structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01659, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'If signalSemaphoreCount is not 0, pSignalSemaphores must be a pointer to an array of signalSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01660, "For more information refer to Vulkan Spec Section '28.7.6. Binding Resource Memory' which states 'Both of the elements of pSignalSemaphores, and the elements of pWaitSemaphores that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBindSparseInfo)"},
+    {VALIDATION_ERROR_01665, "For more information refer to Vulkan Spec Section '30.1. Layers' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceLayerProperties)"},
+    {VALIDATION_ERROR_01666, "For more information refer to Vulkan Spec Section '30.1. Layers' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkLayerProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceLayerProperties)"},
+    {VALIDATION_ERROR_01667, "For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)"},
+    {VALIDATION_ERROR_01668, "For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)"},
+    {VALIDATION_ERROR_01669, "For more information refer to Vulkan Spec Section '30.1.1. Device Layer Deprecation' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkLayerProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceLayerProperties)"},
+    {VALIDATION_ERROR_01670, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, it must be the name of a layer returned by vkEnumerateInstanceLayerProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)"},
+    {VALIDATION_ERROR_01671, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, pLayerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)"},
+    {VALIDATION_ERROR_01672, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)"},
+    {VALIDATION_ERROR_01673, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkExtensionProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateInstanceExtensionProperties)"},
+    {VALIDATION_ERROR_01674, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, it must be the name of a layer returned by vkEnumerateDeviceLayerProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)"},
+    {VALIDATION_ERROR_01675, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)"},
+    {VALIDATION_ERROR_01676, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If pLayerName is not NULL, pLayerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)"},
+    {VALIDATION_ERROR_01677, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)"},
+    {VALIDATION_ERROR_01679, "For more information refer to Vulkan Spec Section '31.1. Features' which states 'pFeatures must be a pointer to a VkPhysicalDeviceFeatures structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFeatures)"},
+    {VALIDATION_ERROR_01680, "For more information refer to Vulkan Spec Section '31.1. Features' which states 'If any member of this structure is VK_FALSE, as returned by vkGetPhysicalDeviceFeatures, then it must be VK_FALSE when passed as part of the VkDeviceCreateInfo struct when creating a device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#features-features-inheritedQueries)"},
+    {VALIDATION_ERROR_01683, "For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)"},
+    {VALIDATION_ERROR_01684, "For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)"},
+    {VALIDATION_ERROR_01685, "For more information refer to Vulkan Spec Section '31.3.2. Format Properties' which states 'pFormatProperties must be a pointer to a VkFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFormatProperties)"},
+    {VALIDATION_ERROR_01686, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01687, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01688, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01689, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01690, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01691, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01692, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01693, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'pImageFormatProperties must be a pointer to a VkImageFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceImageFormatProperties)"},
+    {VALIDATION_ERROR_01694, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'sType must be VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01695, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01696, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireSyncs must be a pointer to an array of acquireCount valid VkDeviceMemory handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01697, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireKeys must be a pointer to an array of acquireCount uint64_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01698, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If acquireCount is not 0, pAcquireTimeoutMilliseconds must be a pointer to an array of acquireCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01699, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If releaseCount is not 0, pReleaseSyncs must be a pointer to an array of releaseCount valid VkDeviceMemory handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01700, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'If releaseCount is not 0, pReleaseKeys must be a pointer to an array of releaseCount uint64_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01701, "For more information refer to Vulkan Spec Section '5.4. Command Buffer Submission' which states 'Both of the elements of pAcquireSyncs, and the elements of pReleaseSyncs that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32KeyedMutexAcquireReleaseInfoNV)"},
+    {VALIDATION_ERROR_01702, "For more information refer to Vulkan Spec Section '7.4. Render Pass Commands' which states 'renderPass must be compatible with the renderPass member of the VkFramebufferCreateInfo structure specified when creating framebuffer.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkRenderPassBeginInfo)"},
+    {VALIDATION_ERROR_01703, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'At least one of image and buffer must be VK_NULL_HANDLE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01704, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, the image must have been created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01705, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, the buffer must have been created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01706, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01707, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, VkMemoryAllocateInfo::allocationSize must equal the VkMemoryRequirements::size of the buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01708, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01709, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01710, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If image is not VK_NULL_HANDLE, image must be a valid VkImage handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01711, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'If buffer is not VK_NULL_HANDLE, buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01712, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'Both of buffer, and image that are valid handles must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01713, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01714, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01715, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01716, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryAllocateInfoNV)"},
+    {VALIDATION_ERROR_01717, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)"},
+    {VALIDATION_ERROR_01718, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)"},
+    {VALIDATION_ERROR_01719, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pAttributes must be a pointer to a valid SECURITY_ATTRIBUTES value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExportMemoryWin32HandleInfoNV)"},
+    {VALIDATION_ERROR_01720, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'sType must be VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)"},
+    {VALIDATION_ERROR_01721, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)"},
+    {VALIDATION_ERROR_01722, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)"},
+    {VALIDATION_ERROR_01723, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryHandleTypeFlagBitsNV)"},
+    {VALIDATION_ERROR_01724, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a flag specified in VkExportMemoryAllocateInfoNV::handleTypes when allocating memory' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01725, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01726, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'memory must be a valid VkDeviceMemory handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01727, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01728, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'handleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01729, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'pHandle must be a pointer to a HANDLE value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01730, "For more information refer to Vulkan Spec Section '10.2. Device Memory' which states 'memory must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetMemoryWin32HandleNV)"},
+    {VALIDATION_ERROR_01731, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'If dedicatedAllocation is VK_TRUE, VkBufferCreateInfo::flags must not include VK_BUFFER_CREATE_SPARSE_BINDING_BIT, VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or VK_BUFFER_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)"},
+    {VALIDATION_ERROR_01732, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)"},
+    {VALIDATION_ERROR_01733, "For more information refer to Vulkan Spec Section '11.1. Buffers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationBufferCreateInfoNV)"},
+    {VALIDATION_ERROR_01734, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If dedicatedAllocation is VK_TRUE, VkImageCreateInfo::flags must not include VK_IMAGE_CREATE_SPARSE_BINDING_BIT, VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01735, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01736, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDedicatedAllocationImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01737, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'sType must be VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01738, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01739, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'handleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01740, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'handleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalMemoryImageCreateInfoNV)"},
+    {VALIDATION_ERROR_01741, "For more information refer to Vulkan Spec Section '11.8. Memory Aliasing' which states 'If either magFilter or minFilter is VK_FILTER_CUBIC_IMG, anisotropyEnable must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSamplerAddressMode)"},
+    {VALIDATION_ERROR_01742, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01743, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01744, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01745, "For more information refer to Vulkan Spec Section '18.3. Copying Data Between Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCopy)"},
+    {VALIDATION_ERROR_01746, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D, then imageOffset.y must be 0 and imageExtent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01747, "For more information refer to Vulkan Spec Section '18.4. Copying Data Between Buffers and Images' which states 'If the calling commands srcImage (vkCmdCopyImageToBuffer) or dstImage (vkCmdCopyBufferToImage) is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then imageOffset.z must be 0 and imageExtent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferImageCopy)"},
+    {VALIDATION_ERROR_01748, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset[0].y must be 0 and srcOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01749, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset[0].z must be 0 and srcOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01750, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset[0].y must be 0 and dstOffset[1].y must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01751, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset[0].z must be 0 and dstOffset[1].z must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageBlit)"},
+    {VALIDATION_ERROR_01752, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.x and (extent.width + srcOffset.x) must both be greater than or equal to 0 and less than or equal to the source image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01753, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.y and (extent.height + srcOffset.y) must both be greater than or equal to 0 and less than or equal to the source image subresource heightIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01754, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D, then srcOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01755, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'srcOffset.z and (extent.depth + srcOffset.z) must both be greater than or equal to 0 and less than or equal to the source image subresource depthIf the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01756, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands srcImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then srcOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01757, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.x and (extent.width + dstOffset.x) must both be greater than or equal to 0 and less than or equal to the destination image subresource width' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01758, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.y and (extent.height + dstOffset.y) must both be greater than or equal to 0 and less than or equal to the destination image subresource heightIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01759, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D, then dstOffset.y must be 0 and extent.height must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01760, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'dstOffset.z and (extent.depth + dstOffset.z) must both be greater than or equal to 0 and less than or equal to the destination image subresource depthIf the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01761, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If the calling commands dstImage is of type VK_IMAGE_TYPE_1D or VK_IMAGE_TYPE_2D, then dstOffset.z must be 0 and extent.depth must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageResolve)"},
+    {VALIDATION_ERROR_01762, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01763, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_01764, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01765, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_01766, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01767, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01768, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01769, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If maxDrawCount is greater than or equal to 1, (stride  (maxDrawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01770, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01771, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01772, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01773, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01774, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01775, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01776, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01777, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_01778, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01779, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBufferOffset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01780, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'stride must be a multiple of 4 and must be greater than or equal to sizeof(VkDrawIndirectCommand)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01781, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If maxDrawCount is greater than or equal to 1, (stride  (maxDrawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01782, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, all the firstInstance members of the VkDrawIndexedIndirectCommand structures accessed by this command must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01783, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01784, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'buffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01785, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'countBuffer must be a valid VkBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01786, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01787, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01788, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'This command must only be called inside of a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01789, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Each of buffer, commandBuffer, and countBuffer must have been created, allocated, or retrieved from the same VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_01790, "For more information refer to Vulkan Spec Section '23.5. Controlling the Viewport' which states 'If the VK_AMD_negative_viewport_height extension is enabled, height can also be negative.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkViewport)"},
+    {VALIDATION_ERROR_01791, "For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'sType must be VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)"},
+    {VALIDATION_ERROR_01792, "For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)"},
+    {VALIDATION_ERROR_01793, "For more information refer to Vulkan Spec Section '24.2. Rasterization Order' which states 'rasterizationOrder must be a valid VkRasterizationOrderAMD value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineRasterizationStateRasterizationOrderAMD)"},
+    {VALIDATION_ERROR_01794, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)"},
+    {VALIDATION_ERROR_01795, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pCreateInfo must be a pointer to a valid VkAndroidSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)"},
+    {VALIDATION_ERROR_01796, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)"},
+    {VALIDATION_ERROR_01797, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateAndroidSurfaceKHR)"},
+    {VALIDATION_ERROR_01798, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'sType must be VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01799, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01800, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01801, "For more information refer to Vulkan Spec Section '29.2.1. Android Platform' which states 'window must be a pointer to a ANativeWindow value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkAndroidSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01802, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)"},
+    {VALIDATION_ERROR_01803, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pCreateInfo must be a pointer to a valid VkMirSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)"},
+    {VALIDATION_ERROR_01804, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)"},
+    {VALIDATION_ERROR_01805, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateMirSurfaceKHR)"},
+    {VALIDATION_ERROR_01806, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'sType must be VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01807, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01808, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01809, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'connection must be a pointer to a MirConnection value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01810, "For more information refer to Vulkan Spec Section '29.2.2. Mir Platform' which states 'mirSurface must be a pointer to a MirSurface value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkMirSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01811, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)"},
+    {VALIDATION_ERROR_01812, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pCreateInfo must be a pointer to a valid VkWaylandSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)"},
+    {VALIDATION_ERROR_01813, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)"},
+    {VALIDATION_ERROR_01814, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWaylandSurfaceKHR)"},
+    {VALIDATION_ERROR_01815, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'sType must be VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01816, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01817, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01818, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'display must be a pointer to a wl_display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01819, "For more information refer to Vulkan Spec Section '29.2.3. Wayland Platform' which states 'surface must be a pointer to a wl_surface value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWaylandSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01820, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)"},
+    {VALIDATION_ERROR_01821, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pCreateInfo must be a pointer to a valid VkWin32SurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)"},
+    {VALIDATION_ERROR_01822, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)"},
+    {VALIDATION_ERROR_01823, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateWin32SurfaceKHR)"},
+    {VALIDATION_ERROR_01824, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'sType must be VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01825, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01826, "For more information refer to Vulkan Spec Section '29.2.4. Win32 Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkWin32SurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01827, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)"},
+    {VALIDATION_ERROR_01828, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pCreateInfo must be a pointer to a valid VkXcbSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)"},
+    {VALIDATION_ERROR_01829, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)"},
+    {VALIDATION_ERROR_01830, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXcbSurfaceKHR)"},
+    {VALIDATION_ERROR_01831, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'sType must be VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01832, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01833, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01834, "For more information refer to Vulkan Spec Section '29.2.5. XCB Platform' which states 'connection must be a pointer to a xcb_connection_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXcbSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01836, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)"},
+    {VALIDATION_ERROR_01837, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pCreateInfo must be a pointer to a valid VkXlibSurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)"},
+    {VALIDATION_ERROR_01838, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)"},
+    {VALIDATION_ERROR_01839, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateXlibSurfaceKHR)"},
+    {VALIDATION_ERROR_01840, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'sType must be VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01841, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01842, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01843, "For more information refer to Vulkan Spec Section '29.2.6. Xlib Platform' which states 'dpy must be a pointer to a Display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkXlibSurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01844, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'All VkSwapchainKHR objects created for surface must have been destroyed prior to destroying surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01845, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If VkAllocationCallbacks were provided when surface was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01846, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If no VkAllocationCallbacks were provided when surface was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01847, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01848, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If surface is not VK_NULL_HANDLE, surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01849, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01850, "For more information refer to Vulkan Spec Section '29.2.7. Platform-Independent Information' which states 'If surface is a valid handle, it must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySurfaceKHR)"},
+    {VALIDATION_ERROR_01851, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)"},
+    {VALIDATION_ERROR_01852, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)"},
+    {VALIDATION_ERROR_01853, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPropertiesKHR)"},
+    {VALIDATION_ERROR_01854, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)"},
+    {VALIDATION_ERROR_01855, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)"},
+    {VALIDATION_ERROR_01856, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayPlanePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceDisplayPlanePropertiesKHR)"},
+    {VALIDATION_ERROR_01857, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'planeIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)"},
+    {VALIDATION_ERROR_01858, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)"},
+    {VALIDATION_ERROR_01859, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pDisplayCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)"},
+    {VALIDATION_ERROR_01860, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pDisplayCount is not 0, and pDisplays is not NULL, pDisplays must be a pointer to an array of pDisplayCount VkDisplayKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneSupportedDisplaysKHR)"},
+    {VALIDATION_ERROR_01861, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)"},
+    {VALIDATION_ERROR_01862, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)"},
+    {VALIDATION_ERROR_01863, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pPropertyCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)"},
+    {VALIDATION_ERROR_01864, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkDisplayModePropertiesKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayModePropertiesKHR)"},
+    {VALIDATION_ERROR_01865, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)"},
+    {VALIDATION_ERROR_01866, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'display must be a valid VkDisplayKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)"},
+    {VALIDATION_ERROR_01867, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pCreateInfo must be a pointer to a valid VkDisplayModeCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)"},
+    {VALIDATION_ERROR_01868, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)"},
+    {VALIDATION_ERROR_01869, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pMode must be a pointer to a VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayModeKHR)"},
+    {VALIDATION_ERROR_01870, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'The width and height members of the visibleRegion member of parameters must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)"},
+    {VALIDATION_ERROR_01871, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'The refreshRate member of parameters must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)"},
+    {VALIDATION_ERROR_01872, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)"},
+    {VALIDATION_ERROR_01873, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)"},
+    {VALIDATION_ERROR_01874, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayModeCreateInfoKHR)"},
+    {VALIDATION_ERROR_01875, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01876, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'mode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01877, "For more information refer to Vulkan Spec Section '29.3.1. Display Enumeration' which states 'pCapabilities must be a pointer to a VkDisplayPlaneCapabilitiesKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetDisplayPlaneCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01878, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)"},
+    {VALIDATION_ERROR_01879, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pCreateInfo must be a pointer to a valid VkDisplaySurfaceCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)"},
+    {VALIDATION_ERROR_01880, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)"},
+    {VALIDATION_ERROR_01881, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pSurface must be a pointer to a VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDisplayPlaneSurfaceKHR)"},
+    {VALIDATION_ERROR_01882, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'planeIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01883, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01884, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01885, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01886, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'displayMode must be a valid VkDisplayModeKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01887, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'transform must be a valid VkSurfaceTransformFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01888, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'alphaMode must be a valid VkDisplayPlaneAlphaFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_01889, "For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)"},
+    {VALIDATION_ERROR_01890, "For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)"},
+    {VALIDATION_ERROR_01891, "For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)"},
+    {VALIDATION_ERROR_01892, "For more information refer to Vulkan Spec Section '29.4. Querying for WSI Support' which states 'pSupported must be a pointer to a VkBool32 value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceSupportKHR)"},
+    {VALIDATION_ERROR_01893, "For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01894, "For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01895, "For more information refer to Vulkan Spec Section '29.4.2. Mir Platform' which states 'connection must be a pointer to a MirConnection value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceMirPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01896, "For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01897, "For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01898, "For more information refer to Vulkan Spec Section '29.4.3. Wayland Platform' which states 'display must be a pointer to a wl_display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWaylandPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01899, "For more information refer to Vulkan Spec Section '29.4.4. Win32 Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWin32PresentationSupportKHR)"},
+    {VALIDATION_ERROR_01900, "For more information refer to Vulkan Spec Section '29.4.4. Win32 Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceWin32PresentationSupportKHR)"},
+    {VALIDATION_ERROR_01901, "For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01902, "For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01903, "For more information refer to Vulkan Spec Section '29.4.5. XCB Platform' which states 'connection must be a pointer to a xcb_connection_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXcbPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01904, "For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'queueFamilyIndex must be less than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties for the given physicalDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01905, "For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01906, "For more information refer to Vulkan Spec Section '29.4.6. Xlib Platform' which states 'dpy must be a pointer to a Display value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceXlibPresentationSupportKHR)"},
+    {VALIDATION_ERROR_01907, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01908, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01909, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pSurfaceCapabilities must be a pointer to a VkSurfaceCapabilitiesKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceCapabilitiesKHR)"},
+    {VALIDATION_ERROR_01910, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)"},
+    {VALIDATION_ERROR_01911, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)"},
+    {VALIDATION_ERROR_01912, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pSurfaceFormatCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)"},
+    {VALIDATION_ERROR_01913, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'If the value referenced by pSurfaceFormatCount is not 0, and pSurfaceFormats is not NULL, pSurfaceFormats must be a pointer to an array of pSurfaceFormatCount VkSurfaceFormatKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfaceFormatsKHR)"},
+    {VALIDATION_ERROR_01914, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)"},
+    {VALIDATION_ERROR_01915, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)"},
+    {VALIDATION_ERROR_01916, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'pPresentModeCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)"},
+    {VALIDATION_ERROR_01917, "For more information refer to Vulkan Spec Section '29.5. Surface Queries' which states 'If the value referenced by pPresentModeCount is not 0, and pPresentModes is not NULL, pPresentModes must be a pointer to an array of pPresentModeCount VkPresentModeKHR values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceSurfacePresentModesKHR)"},
+    {VALIDATION_ERROR_01918, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)"},
+    {VALIDATION_ERROR_01919, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pCreateInfo must be a pointer to a valid VkSwapchainCreateInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)"},
+    {VALIDATION_ERROR_01920, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)"},
+    {VALIDATION_ERROR_01921, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchain must be a pointer to a VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSwapchainKHR)"},
+    {VALIDATION_ERROR_01922, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'surface must be a surface that is supported by the device as determined using vkGetPhysicalDeviceSurfaceSupportKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01923, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01924, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01925, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'flags must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01926, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'surface must be a valid VkSurfaceKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01927, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageFormat must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01928, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageColorSpace must be a valid VkColorSpaceKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01929, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01930, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01931, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageSharingMode must be a valid VkSharingMode value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01932, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'preTransform must be a valid VkSurfaceTransformFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01933, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'compositeAlpha must be a valid VkCompositeAlphaFlagBitsKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01934, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'presentMode must be a valid VkPresentModeKHR value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01935, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If oldSwapchain is not VK_NULL_HANDLE, oldSwapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01936, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If oldSwapchain is a valid handle, it must have been created, allocated, or retrieved from surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_01937, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'All uses of presentable images acquired from swapchain must have completed execution' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01938, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If VkAllocationCallbacks were provided when swapchain was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01939, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If no VkAllocationCallbacks were provided when swapchain was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01940, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01941, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If swapchain is not VK_NULL_HANDLE, swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01942, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroySwapchainKHR)"},
+    {VALIDATION_ERROR_01943, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)"},
+    {VALIDATION_ERROR_01944, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pCreateInfos must be a pointer to an array of swapchainCount valid VkSwapchainCreateInfoKHR structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)"},
+    {VALIDATION_ERROR_01945, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)"},
+    {VALIDATION_ERROR_01946, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchains must be a pointer to an array of swapchainCount VkSwapchainKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)"},
+    {VALIDATION_ERROR_01947, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchainCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateSharedSwapchainsKHR)"},
+    {VALIDATION_ERROR_01948, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)"},
+    {VALIDATION_ERROR_01949, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)"},
+    {VALIDATION_ERROR_01950, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchainImageCount must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)"},
+    {VALIDATION_ERROR_01951, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If the value referenced by pSwapchainImageCount is not 0, and pSwapchainImages is not NULL, pSwapchainImages must be a pointer to an array of pSwapchainImageCount VkImage handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetSwapchainImagesKHR)"},
+    {VALIDATION_ERROR_01952, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is not VK_NULL_HANDLE it must be unsignaled' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01953, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is not VK_NULL_HANDLE it must be unsignaled and must not be associated with any other queue command that has not yet completed execution on that queue' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01954, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01955, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchain must be a valid VkSwapchainKHR handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01956, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is not VK_NULL_HANDLE, semaphore must be a valid VkSemaphore handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01957, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is not VK_NULL_HANDLE, fence must be a valid VkFence handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01958, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pImageIndex must be a pointer to a uint32_t value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01959, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If semaphore is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01960, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If fence is a valid handle, it must have been created, allocated, or retrieved from device' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkAcquireNextImageKHR)"},
+    {VALIDATION_ERROR_01961, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of pSwapchains member of pPresentInfo must be a swapchain that is created for a surface for which presentation is supported from queue as determined using a call to vkGetPhysicalDeviceSurfaceSupportKHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)"},
+    {VALIDATION_ERROR_01962, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'queue must be a valid VkQueue handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)"},
+    {VALIDATION_ERROR_01963, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pPresentInfo must be a pointer to a valid VkPresentInfoKHR structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)"},
+    {VALIDATION_ERROR_01964, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of pImageIndices must be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pSwapchains array' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01965, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'Any given element of VkSemaphore in pWaitSemaphores must refer to a prior signal of that VkSemaphore that will not be consumed by any other wait on that semaphore' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01966, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_PRESENT_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01967, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01968, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If waitSemaphoreCount is not 0, and pWaitSemaphores is not NULL, pWaitSemaphores must be a pointer to an array of waitSemaphoreCount valid VkSemaphore handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01969, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pSwapchains must be a pointer to an array of swapchainCount valid VkSwapchainKHR handles' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01970, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pImageIndices must be a pointer to an array of swapchainCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01971, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If pResults is not NULL, pResults must be a pointer to an array of swapchainCount VkResult values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01972, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'swapchainCount must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPresentInfoKHR)"},
+    {VALIDATION_ERROR_01973, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'srcRect must specify a rectangular region that is a subset of the image being presented' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)"},
+    {VALIDATION_ERROR_01974, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'dstRect must specify a rectangular region that is a subset of the visibleRegion parameter of the display mode the swapchain being presented uses' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)"},
+    {VALIDATION_ERROR_01975, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If the persistentContent member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display the present operation targets then persistent must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)"},
+    {VALIDATION_ERROR_01976, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'sType must be VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)"},
+    {VALIDATION_ERROR_01977, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplayPresentInfoKHR)"},
+    {VALIDATION_ERROR_01978, "For more information refer to Vulkan Spec Section '30.2. Extensions' which states 'If the value referenced by pPropertyCount is not 0, and pProperties is not NULL, pProperties must be a pointer to an array of pPropertyCount VkExtensionProperties structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkEnumerateDeviceExtensionProperties)"},
+    {VALIDATION_ERROR_01979, "For more information refer to Vulkan Spec Section '31.1. Features' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceFeatures)"},
+    {VALIDATION_ERROR_01980, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'physicalDevice must be a valid VkPhysicalDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01981, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'format must be a valid VkFormat value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01982, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'type must be a valid VkImageType value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01983, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'tiling must be a valid VkImageTiling value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01984, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must be a valid combination of VkImageUsageFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01985, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'usage must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01986, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must be a valid combination of VkImageCreateFlagBits values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01987, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01988, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalHandleType must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01989, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalHandleType must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01990, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'pExternalImageFormatProperties must be a pointer to a VkExternalImageFormatPropertiesNV structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkGetPhysicalDeviceExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01991, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'imageFormatProperties must be a valid VkImageFormatProperties structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01992, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalMemoryFeatures must be a valid combination of VkExternalMemoryFeatureFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01993, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'externalMemoryFeatures must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01994, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'exportFromImportedHandleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01995, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'exportFromImportedHandleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01996, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'compatibleHandleTypes must be a valid combination of VkExternalMemoryHandleTypeFlagBitsNV values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01997, "For more information refer to Vulkan Spec Section '31.4. Additional Image Capabilities' which states 'compatibleHandleTypes must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkExternalImageFormatPropertiesNV)"},
+    {VALIDATION_ERROR_01998, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNameInfo.object must be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)"},
+    {VALIDATION_ERROR_01999, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)"},
+    {VALIDATION_ERROR_02000, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNameInfo must be a pointer to a VkDebugMarkerObjectNameInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectNameEXT)"},
+    {VALIDATION_ERROR_02001, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)"},
+    {VALIDATION_ERROR_02002, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)"},
+    {VALIDATION_ERROR_02003, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)"},
+    {VALIDATION_ERROR_02004, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pObjectName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectNameInfoEXT)"},
+    {VALIDATION_ERROR_02005, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo.object must be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)"},
+    {VALIDATION_ERROR_02006, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo.tagName must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)"},
+    {VALIDATION_ERROR_02007, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'device must be a valid VkDevice handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)"},
+    {VALIDATION_ERROR_02008, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTagInfo must be a pointer to a VkDebugMarkerObjectTagInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugMarkerSetObjectTagEXT)"},
+    {VALIDATION_ERROR_02009, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)"},
+    {VALIDATION_ERROR_02010, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)"},
+    {VALIDATION_ERROR_02011, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)"},
+    {VALIDATION_ERROR_02012, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'pTag must be a pointer to an array of tagSize bytes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)"},
+    {VALIDATION_ERROR_02013, "For more information refer to Vulkan Spec Section '32.1.1. Object Annotation' which states 'tagSize must be greater than 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerObjectTagInfoEXT)"},
+    {VALIDATION_ERROR_02014, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)"},
+    {VALIDATION_ERROR_02015, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerInfo must be a pointer to a VkDebugMarkerMarkerInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)"},
+    {VALIDATION_ERROR_02016, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)"},
+    {VALIDATION_ERROR_02017, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerBeginEXT)"},
+    {VALIDATION_ERROR_02018, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)"},
+    {VALIDATION_ERROR_02019, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)"},
+    {VALIDATION_ERROR_02020, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerName must be a null-terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugMarkerMarkerInfoEXT)"},
+    {VALIDATION_ERROR_02021, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'There must be an outstanding vkCmdDebugMarkerBeginEXT command prior to the vkCmdDebugMarkerEndEXT on the queue that commandBuffer is submitted to' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)"},
+    {VALIDATION_ERROR_02022, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)"},
+    {VALIDATION_ERROR_02023, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)"},
+    {VALIDATION_ERROR_02024, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)"},
+    {VALIDATION_ERROR_02025, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be a valid VkCommandBuffer handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)"},
+    {VALIDATION_ERROR_02026, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'pMarkerInfo must be a pointer to a VkDebugMarkerMarkerInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)"},
+    {VALIDATION_ERROR_02027, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'commandBuffer must be in the recording state' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)"},
+    {VALIDATION_ERROR_02028, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'The VkCommandPool that commandBuffer was allocated from must support graphics, or compute operations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerInsertEXT)"},
+    {VALIDATION_ERROR_02029, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02030, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pCreateInfo must be a pointer to a valid VkDebugReportCallbackCreateInfoEXT structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02031, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02032, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pCallback must be a pointer to a VkDebugReportCallbackEXT handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCreateDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02033, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'sType must be VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)"},
+    {VALIDATION_ERROR_02034, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pNext must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)"},
+    {VALIDATION_ERROR_02035, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must be a valid combination of VkDebugReportFlagBitsEXT values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)"},
+    {VALIDATION_ERROR_02036, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDebugReportFlagBitsEXT)"},
+    {VALIDATION_ERROR_02040, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'object may be a Vulkan object' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02041, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pLayerPrefix must be a NULL terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02042, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pMessage must be a NULL terminated string' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02043, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02044, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must be a valid combination of VkDebugReportFlagBitsEXT values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02045, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'flags must not be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02046, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'objectType must be a valid VkDebugReportObjectTypeEXT value' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02047, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pLayerPrefix must be a pointer to a valid' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02048, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'pMessage must be a pointer to a valid' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDebugReportMessageEXT)"},
+    {VALIDATION_ERROR_02049, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If VkAllocationCallbacks were provided when instance was created, a compatible set of callbacks must be provided here' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02050, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If no VkAllocationCallbacks were provided when instance was created, pAllocator must be NULL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02051, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'instance must be a valid VkInstance handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02052, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'callback must be a valid VkDebugReportCallbackEXT handle' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02053, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'If pAllocator is not NULL, pAllocator must be a pointer to a valid VkAllocationCallbacks structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02054, "For more information refer to Vulkan Spec Section '32.2. Debug Report Callbacks' which states 'callback must have been created, allocated, or retrieved from instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkDestroyDebugReportCallbackEXT)"},
+    {VALIDATION_ERROR_02055, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'queueCount must be less than or equal to the queueCount member of the VkQueueFamilyProperties structure, as returned by vkGetPhysicalDeviceQueueFamilyProperties in the pQueueFamilyProperties[queueFamilyIndex]' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_02056, "For more information refer to Vulkan Spec Section '4.3.2. Queue Creation' which states 'Each element of pQueuePriorities must be between 0.0 and 1.0 inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDeviceQueueCreateInfo)"},
+    {VALIDATION_ERROR_02057, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02058, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::subpass set to the index of the subpass which the given command buffer will be executed in' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02059, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, any given element of pCommandBuffers must have been recorded with a render pass that is compatible with the current render pass - see Section 7.2, Render Pass Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02060, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is being called within a render pass instance, and any given element of pCommandBuffers was recorded with VkCommandBufferInheritanceInfo::framebuffer not equal to VK_NULL_HANDLE, that VkFramebuffer must match the VkFramebuffer used in the current render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02061, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If vkCmdExecuteCommands is not being called within a render pass instance, any given element of pCommandBuffers must not have been recorded with the VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02062, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If the inherited queries feature is not enabled, commandBuffer must not have any queries active' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02063, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_OCCLUSION query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::occlusionQueryEnable set to VK_TRUE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02064, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_OCCLUSION query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::queryFlags having all bits set that are set for the query' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02065, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'If commandBuffer has a VK_QUERY_TYPE_PIPELINE_STATISTICS query active, then each element of pCommandBuffers must have been recorded with VkCommandBufferInheritanceInfo::pipelineStatistics having all bits set that are set in the VkQueryPool the query uses' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02066, "For more information refer to Vulkan Spec Section '5.6. Secondary Command Buffer Execution' which states 'Any given element of pCommandBuffers must not begin any query types that are active in commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdExecuteCommands)"},
+    {VALIDATION_ERROR_02067, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_02068, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the geometry shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_02069, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, srcStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_02070, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If the tessellation shaders feature is not enabled, dstStageMask must not contain VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_02071, "For more information refer to Vulkan Spec Section '6.3. Events' which states 'If pEvents includes one or more events that will be signaled by vkSetEvent after commandBuffer has been submitted to a queue, then vkCmdWaitEvents must not be called inside a render pass instance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdWaitEvents)"},
+    {VALIDATION_ERROR_02072, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'srcStageMask must contain a subset of the bit values in the srcStageMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02073, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dstStageMask must contain a subset of the bit values in the dstStageMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02074, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The srcAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the srcAccessMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02075, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'The dstAccessMask of any element of pMemoryBarriers or pImageMemoryBarriers must contain a subset of the bit values the dstAccessMask member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02076, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'dependencyFlags must be equal to the dependencyFlags member of that instance of VkSubpassDependency' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02077, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, bufferMemoryBarrierCount must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02078, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the image member of any element of pImageMemoryBarriers must be equal to one of the elements of pAttachments that the current framebuffer was created with, that is also referred to by one of the elements of the pColorAttachments, pResolveAttachments or pDepthStencilAttachment members of the VkSubpassDescription instance that the current subpass was created with' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02079, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the oldLayout and newLayout members of any element of pImageMemoryBarriers must be equal to the layout member of an element of the pColorAttachments, pResolveAttachments or pDepthStencilAttachment members of the VkSubpassDescription instance that the current subpass was created with, that refers to the same image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02080, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the oldLayout and newLayout members of an element of pImageMemoryBarriers must be equal' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02081, "For more information refer to Vulkan Spec Section '6.5. Pipeline Barriers' which states 'If vkCmdPipelineBarrier is called within a render pass instance, the srcQueueFamilyIndex and dstQueueFamilyIndex members of any element of pImageMemoryBarriers must be VK_QUEUE_FAMILY_IGNORED' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdPipelineBarrier)"},
+    {VALIDATION_ERROR_02082, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'pCode must not declare any capability that is not supported by the API, as described by the Capabilities section of the SPIR-V Environment appendix' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_02083, "For more information refer to Vulkan Spec Section '8.1. Shader Modules' which states 'If pCode declares any of the capabilities that are listed as not required by the implementation, the relevant feature must be enabled, as listed in the SPIR-V Environment appendix' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderModuleCreateInfo)"},
+    {VALIDATION_ERROR_02084, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the ClipDistance BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxClipDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02085, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the CullDistance BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxCullDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02086, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variables in its interface that are declared with the ClipDistance or CullDistance BuiltIn decoration, those variables must not have array sizes which sum to more than VkPhysicalDeviceLimits::maxCombinedClipAndCullDistances' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02087, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If the identified entry point includes any variable in its interface that is declared with the SampleMask BuiltIn decoration, that variable must not have an array size greater than VkPhysicalDeviceLimits::maxSampleMaskWords' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02088, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_VERTEX_BIT, the identified entry point must not include any input variable in its interface that is decorated with CullDistance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02089, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, and the identified entry point has an OpExecutionMode instruction that specifies a patch size with OutputVertices, the patch size must be greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxTessellationPatchSize' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02090, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must have an OpExecutionMode instruction that specifies a maximum output vertex count that is greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxGeometryOutputVertices' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02091, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must have an OpExecutionMode instruction that specifies an invocation count that is greater than 0 and less than or equal to VkPhysicalDeviceLimits::maxGeometryShaderInvocations' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02092, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to Layer for any primitive, it must write the same value to Layer for all vertices of a given primitive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02093, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to ViewportIndex for any primitive, it must write the same value to ViewportIndex for all vertices of a given primitive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02094, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_FRAGMENT_BIT, the identified entry point must not include any output variables in its interface decorated with CullDistance' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02095, "For more information refer to Vulkan Spec Section '9.1. Compute Pipelines' which states 'If stage is VK_SHADER_STAGE_FRAGMENT_BIT, and the identified entry point writes to FragDepth in any execution path, it must write to FragDepth in all execution paths' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkShaderStageFlagBits)"},
+    {VALIDATION_ERROR_02096, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both stages contain an OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must both specify the same subdivision mode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02097, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the shader code of at least one stage must contain an OpExecutionMode instruction that specifies the output patch size in the pipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02098, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, and the shader code of both contain an OpExecutionMode instruction that specifies the out patch size in the pipeline, they must both specify the same patch size' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02099, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes tessellation shader stages, the topology member of pInputAssembly must be VK_PRIMITIVE_TOPOLOGY_PATCH_LIST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02100, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the topology member of pInputAssembly is VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pStages must include tessellation shader stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02101, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and does not include any tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology specified in pInputAssembly' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02102, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must contain an OpExecutionMode instruction that specifies an input primitive type that is compatible with the primitive topology that is output by the tessellation stages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02103, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a fragment shader stage and a geometry shader stage, and the fragment shader code reads from an input variable that is decorated with PrimitiveID, then the geometry shader code must write to a matching output variable, decorated with PrimitiveID, in all execution paths' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02104, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pStages includes a fragment shader stage, its shader code must not read from any input attachment that is defined as VK_ATTACHMENT_UNUSED in subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02105, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'The shader code for the entry points identified by pStages, and the rest of the state identified by this structure must adhere to the pipeline linking rules described in the Shader Interfaces chapter' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02106, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses a depth/stencil attachment in renderpass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the VkAttachmentReference defined by subpass, and pDepthStencilState is not NULL, the depthWriteEnable member of pDepthStencilState must be VK_FALSE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02107, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses a depth/stencil attachment in renderpass that has a layout of VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the VkAttachmentReference defined by subpass, and pDepthStencilState is not NULL, the failOp, passOp and depthFailOp members of each of the front and back members of pDepthStencilState must be VK_STENCIL_OP_KEEP' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02108, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pColorBlendState is not NULL, the blendEnable member of each element of the pAttachment member of pColorBlendState must be VK_FALSE if the format of the attachment referred to in subpass of renderPass does not support color blend operations, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT flag in VkFormatProperties::linearTilingFeatures or VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02109, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If pColorBlendState is not NULL, The attachmentCount member of pColorBlendState must be equal to the colorAttachmentCount used to create subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02110, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_VIEWPORT, the pViewports member of pViewportState must be a pointer to an array of pViewportState::viewportCount VkViewport structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02111, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_SCISSOR, the pScissors member of pViewportState must be a pointer to an array of pViewportState::scissorCount VkRect2D structures' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02112, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the wide lines feature is not enabled, and no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_LINE_WIDTH, the lineWidth member of pRasterizationState must be 1.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02113, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pViewportState must be a pointer to a valid VkPipelineViewportStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02114, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, pMultisampleState must be a pointer to a valid VkPipelineMultisampleStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02115, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, and subpass uses a depth/stencil attachment, pDepthStencilState must be a pointer to a valid VkPipelineDepthStencilStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02116, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the rasterizerDiscardEnable member of pRasterizationState is VK_FALSE, and subpass uses color attachments, pColorBlendState must be a pointer to a valid VkPipelineColorBlendStateCreateInfo structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02117, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If the depth bias clamping feature is not enabled, no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_DEPTH_BIAS, and the depthBiasEnable member of pDepthStencil is VK_TRUE, the depthBiasClamp member of pDepthStencil must be 0.0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02118, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If no element of the pDynamicStates member of pDynamicState is VK_DYNAMIC_STATE_DEPTH_BOUNDS, and the depthBoundsTestEnable member of pDepthStencil is VK_TRUE, the minDepthBounds and maxDepthBounds members of pDepthStencil must be between 0.0 and 1.0, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02119, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'layout must be consistent with all shaders specified in pStages' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02120, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass uses color and/or depth/stencil attachments, then the rasterizationSamples member of pMultisampleState must be the same as the sample count for those subpass attachments' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02121, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'If subpass does not use any color and/or depth/stencil attachments, then the rasterizationSamples member of pMultisampleState must follow the rules for a zero-attachment subpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02122, "For more information refer to Vulkan Spec Section '9.2. Graphics Pipelines' which states 'subpass must be a valid subpass within renderpass' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCreateFlagBits)"},
+    {VALIDATION_ERROR_02123, "For more information refer to Vulkan Spec Section '9.6. Pipeline Cache' which states 'If initialDataSize is not 0, pInitialData must have been retrieved from a previous call to vkGetPipelineCacheData' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkPipelineCacheCreateInfo)"},
+    {VALIDATION_ERROR_02124, "For more information refer to Vulkan Spec Section '11.2. Buffer Views' which states 'If buffer was created with usage containing VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, format must be supported for storage texel buffers, as specified by the VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT flag in VkFormatProperties::bufferFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkBufferViewCreateInfo)"},
+    {VALIDATION_ERROR_02125, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags does not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension2D, or VkImageFormatProperties::maxExtent.width/height (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02126, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be less than or equal to VkPhysicalDeviceLimits::maxImageDimensionCube, or VkImageFormatProperties::maxExtent.width/height (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02127, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D and flags contains VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, extent.width and extent.height must be equal and arrayLayers must be greater than or equal to 6' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02128, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_3D, extent.width, extent.height and extent.depth must be less than or equal to VkPhysicalDeviceLimits::maxImageDimension3D, or VkImageFormatProperties::maxExtent.width/height/depth (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure) - whichever is higher' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02129, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_1D, both extent.height and extent.depth must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02130, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_2D, extent.depth must be 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02131, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'mipLevels must be less than or equal to log2(max(extent.width, extent.height, extent.depth)) + 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02132, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If any of extent.width, extent.height, or extent.depth are greater than the equivalently named members of VkPhysicalDeviceLimits::maxImageDimension3D, mipLevels must be less than or equal to VkImageFormatProperties::maxMipLevels (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02133, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'arrayLayers must be less than or equal to VkImageFormatProperties::maxArrayLayers (as returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02134, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If samples is not VK_SAMPLE_COUNT_1_BIT, imageType must be VK_IMAGE_TYPE_2D, flags must not contain VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, tiling must be VK_IMAGE_TILING_OPTIMAL, and mipLevels must be equal to 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02135, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, then bits other than VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT must not be set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02136, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.width must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferWidth' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02137, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If usage includes VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, extent.height must be less than or equal to VkPhysicalDeviceLimits::maxFramebufferHeight' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02138, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'samples must be a bit value that is set in VkImageFormatProperties::sampleCounts returned by vkGetPhysicalDeviceImageFormatProperties with format, type, tiling, usage, and flags equal to those in this structure' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02139, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the ETC2 texture compression feature is not enabled, format must not be VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, VK_FORMAT_EAC_R11_UNORM_BLOCK, VK_FORMAT_EAC_R11_SNORM_BLOCK, VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or VK_FORMAT_EAC_R11G11_SNORM_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02140, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the ASTC LDR texture compression feature is not enabled, format must not be VK_FORMAT_ASTC_4x4_UNORM_BLOCK, VK_FORMAT_ASTC_4x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x4_UNORM_BLOCK, VK_FORMAT_ASTC_5x4_SRGB_BLOCK, VK_FORMAT_ASTC_5x5_UNORM_BLOCK, VK_FORMAT_ASTC_5x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x5_UNORM_BLOCK, VK_FORMAT_ASTC_6x5_SRGB_BLOCK, VK_FORMAT_ASTC_6x6_UNORM_BLOCK, VK_FORMAT_ASTC_6x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x5_UNORM_BLOCK, VK_FORMAT_ASTC_8x5_SRGB_BLOCK, VK_FORMAT_ASTC_8x6_UNORM_BLOCK, VK_FORMAT_ASTC_8x6_SRGB_BLOCK, VK_FORMAT_ASTC_8x8_UNORM_BLOCK, VK_FORMAT_ASTC_8x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x5_UNORM_BLOCK, VK_FORMAT_ASTC_10x5_SRGB_BLOCK, VK_FORMAT_ASTC_10x6_UNORM_BLOCK, VK_FORMAT_ASTC_10x6_SRGB_BLOCK, VK_FORMAT_ASTC_10x8_UNORM_BLOCK, VK_FORMAT_ASTC_10x8_SRGB_BLOCK, VK_FORMAT_ASTC_10x10_UNORM_BLOCK, VK_FORMAT_ASTC_10x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x10_UNORM_BLOCK, VK_FORMAT_ASTC_12x10_SRGB_BLOCK, VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or VK_FORMAT_ASTC_12x12_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02141, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the BC texture compression feature is not enabled, format must not be VK_FORMAT_BC1_RGB_UNORM_BLOCK, VK_FORMAT_BC1_RGB_SRGB_BLOCK, VK_FORMAT_BC1_RGBA_UNORM_BLOCK, VK_FORMAT_BC1_RGBA_SRGB_BLOCK, VK_FORMAT_BC2_UNORM_BLOCK, VK_FORMAT_BC2_SRGB_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_SRGB_BLOCK, VK_FORMAT_BC4_UNORM_BLOCK, VK_FORMAT_BC4_SNORM_BLOCK, VK_FORMAT_BC5_UNORM_BLOCK, VK_FORMAT_BC5_SNORM_BLOCK, VK_FORMAT_BC6H_UFLOAT_BLOCK, VK_FORMAT_BC6H_SFLOAT_BLOCK, VK_FORMAT_BC7_UNORM_BLOCK, or VK_FORMAT_BC7_SRGB_BLOCK' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02142, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the multisampled storage images feature is not enabled, and usage contains VK_IMAGE_USAGE_STORAGE_BIT, samples must be VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02143, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse bindings feature is not enabled, flags must not contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02144, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for 2D images feature is not enabled, and imageType is VK_IMAGE_TYPE_2D, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02145, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for 3D images feature is not enabled, and imageType is VK_IMAGE_TYPE_3D, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02146, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 2 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_2_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02147, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 4 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_4_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02148, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 8 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_8_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02149, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If the sparse residency for images with 16 samples feature is not enabled, imageType is VK_IMAGE_TYPE_2D, and samples is VK_SAMPLE_COUNT_16_BIT, flags must not contain VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02150, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, format must be a format that has at least one supported feature bit present in the value of VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02151, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_SAMPLED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02152, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_STORAGE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02153, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02154, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_LINEAR, and VkFormatProperties::linearTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02155, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, format must be a format that has at least one supported feature bit present in the value of VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02156, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_SAMPLED_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02157, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, usage must not contain VK_IMAGE_USAGE_STORAGE_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02158, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02159, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If tiling is VK_IMAGE_TILING_OPTIMAL, and VkFormatProperties::optimalTilingFeatures (as returned by vkGetPhysicalDeviceFormatProperties with the same value of format) does not include VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, usage must not contain VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02160, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If flags contains VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must also contain VK_IMAGE_CREATE_SPARSE_BINDING_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02161, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_SAMPLED_BIT, format must be supported for sampled images, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02162, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_STORAGE_BIT, format must be supported for storage images, as specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02163, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02164, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_LINEAR and usage containing VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format must be supported for depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::linearTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02165, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL, format must be format that has at least one supported feature bit present in the value of VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02166, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_SAMPLED_BIT, format must be supported for sampled images, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02167, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_STORAGE_BIT, format must be supported for storage images, as specified by the VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02168, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, format must be supported for color attachments, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02169, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with VK_IMAGE_TILING_OPTIMAL and usage containing VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, format must be supported for depth/stencil attachments, as specified by the VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties with the same value of format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02170, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subresourceRange must be a valid image subresource range for image (see Section 11.5, Image Views)' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02171, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, format must be compatible with the format used to create image, as defined in Format Compatibility Classes' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02172, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'If image was not created with the VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, format must be identical to the format used to create image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02173, "For more information refer to Vulkan Spec Section '11.5. Image Views' which states 'subResourceRange and viewType must be compatible with the image, as described in the compatibility table' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#resources-image-views-compatibility)"},
+    {VALIDATION_ERROR_02174, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_02175, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'The size member of the VkMemoryRequirements structure returned from a call to vkGetBufferMemoryRequirements with buffer must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_02176, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::buffer equal to buffer and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_02177, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If buffer was not created with VkDedicatedAllocationBufferCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindBufferMemory)"},
+    {VALIDATION_ERROR_02178, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'memoryOffset must be an integer multiple of the alignment member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_02179, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'The size member of the VkMemoryRequirements structure returned from a call to vkGetImageMemoryRequirements with image must be less than or equal to the size of memory minus memoryOffset' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_02180, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If image was created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must have been created with VkDedicatedAllocationMemoryAllocateInfoNV::image equal to image and memoryOffset must be zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_02181, "For more information refer to Vulkan Spec Section '11.6. Resource Memory Association' which states 'If image was not created with VkDedicatedAllocationImageCreateInfoNV::dedicatedAllocation equal to VK_TRUE, memory must not have been allocated dedicated for a specific buffer or image' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkBindImageMemory)"},
+    {VALIDATION_ERROR_02182, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must have been created with VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02183, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must specify the layout of the image subresources of srcImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02184, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02185, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must use a format that supports VK_FORMAT_FEATURE_BLIT_DST_BIT, which is indicated by VkFormatProperties::linearTilingFeatures (for linear tiled images) or VkFormatProperties::optimalTilingFeatures (for optimally tiled images) - as returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02186, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must have been created with VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02187, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must specify the layout of the image subresources of dstImage specified in pRegions at the time this command is executed on a VkDevice' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02188, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImageLayout must be either of VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or VK_IMAGE_LAYOUT_GENERAL' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02189, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'The sample count of srcImage and dstImage must both be equal to VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02190, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with a signed integer VkFormat, the other must also have been created with a signed integer VkFormat' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02191, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with an unsigned integer VkFormat, the other must also have been created with an unsigned integer VkFormat' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02192, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If either of srcImage or dstImage was created with a depth/stencil format, the other must have exactly the same format' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02193, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If srcImage was created with a depth/stencil format, filter must be VK_FILTER_NEAREST' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02194, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'srcImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02195, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'dstImage must have been created with a samples value of VK_SAMPLE_COUNT_1_BIT' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02196, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_LINEAR, srcImage must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02197, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_CUBIC_IMG, srcImage must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02198, "For more information refer to Vulkan Spec Section '18.5. Image Copies with Scaling' which states 'If filter is VK_FILTER_CUBIC_IMG, srcImage must have a VkImageType of VK_IMAGE_TYPE_3D' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdBlitImage)"},
+    {VALIDATION_ERROR_02199, "For more information refer to Vulkan Spec Section '18.6. Resolving Multisample Images' which states 'If dstImage was created with tiling equal to VK_IMAGE_TILING_OPTIMAL, dstImage must have been created with a format that supports being a color attachment, as specified by the VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in VkFormatProperties::optimalTilingFeatures returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdResolveImage)"},
+    {VALIDATION_ERROR_02200, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02201, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02202, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02203, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02204, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02205, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02206, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02207, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02208, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02209, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02210, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02211, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02212, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDraw)"},
+    {VALIDATION_ERROR_02213, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02214, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For a given vertex buffer binding, any attribute data fetched must be entirely contained within the corresponding vertex buffer binding, as described in Section 20.2, Vertex Input Description' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02215, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02216, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02217, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states '(indexSize * (firstIndex + indexCount) + offset) must be less than or equal to the size of the currently bound index buffer, with indexSize being based on the type specified by indexType, where the index buffer, indexType, and offset are specified via vkCmdBindIndexBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02218, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02219, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02220, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02221, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02222, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02223, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02224, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02225, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02226, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexed)"},
+    {VALIDATION_ERROR_02227, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02228, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02229, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02230, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02231, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02232, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02233, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02234, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02235, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is equal to 1, (offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02236, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02237, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02238, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02239, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02240, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02241, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02242, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02243, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02244, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02245, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02246, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirect)"},
+    {VALIDATION_ERROR_02247, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02248, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02249, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02250, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02251, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02252, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02253, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02254, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02255, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02256, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the count stored in countBuffer is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02257, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The count stored in countBuffer must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02258, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02259, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02260, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02261, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02262, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02263, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02264, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndirectCountAMD)"},
+    {VALIDATION_ERROR_02265, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02266, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02267, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02268, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02269, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02270, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02271, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02272, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02273, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02274, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If drawCount is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02275, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02276, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02277, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02278, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02279, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02280, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02281, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02282, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02283, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02284, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirect)"},
+    {VALIDATION_ERROR_02285, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the drawIndirectFirstInstance feature is not enabled, firstInstance must be 0' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDrawIndexedIndirectCommand)"},
+    {VALIDATION_ERROR_02286, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The current render pass must be compatible with the renderPass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02287, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'The subpass index of the current render pass must be equal to the subpass member of the VkGraphicsPipelineCreateInfo structure specified when creating the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02288, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each set n that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must have been bound to n at VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for set n, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02289, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must have been set for VK_PIPELINE_BIND_POINT_GRAPHICS, with a VkPipelineLayout that is compatible for push constants, with the VkPipelineLayout used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02290, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Descriptors in each bound descriptor set, specified via vkCmdBindDescriptorSets, must be valid if they are statically used by the currently bound VkPipeline object, specified via vkCmdBindPipeline' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02291, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'All vertex input bindings accessed via vertex input variables declared in the vertex shader entry points interface must have valid buffers bound' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02292, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'A valid graphics pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_GRAPHICS' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02293, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must have been set on the current command buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02294, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If count stored in countBuffer is equal to 1, (offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02295, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If count stored in countBuffer is greater than 1, (stride  (drawCount - 1) + offset + sizeof(VkDrawIndexedIndirectCommand)) must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02296, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'drawCount must be less than or equal to VkPhysicalDeviceLimits::maxDrawIndirectCount' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02297, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Every input attachment used by the current subpass must be bound to the pipeline via a descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02298, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02299, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02300, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02301, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02302, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02303, "For more information refer to Vulkan Spec Section '19.2. Programmable Primitive Shading' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDrawIndexedIndirectCountAMD)"},
+    {VALIDATION_ERROR_02304, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'A valid compute pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02305, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with the one used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02306, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02307, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02308, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02309, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02310, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02311, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02312, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02313, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatch)"},
+    {VALIDATION_ERROR_02314, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'A valid compute pipeline must be bound to the current command buffer with VK_PIPELINE_BIND_POINT_COMPUTE' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02315, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'buffer must have been created with the VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02316, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'offset must be a multiple of 4' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02317, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'The sum of offset and the size of VkDispatchIndirectCommand must be less than or equal to the size of buffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02318, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'For each push constant that is statically used by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must have been set for VK_PIPELINE_BIND_POINT_COMPUTE, with a VkPipelineLayout that is compatible for push constants with the one used to create the current VkPipeline, as described in the section called Pipeline Layout Compatibility' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02319, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used to sample from any VkImage with a VkImageView of the type VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, VK_IMAGE_VIEW_TYPE_1D_ARRAY, VK_IMAGE_VIEW_TYPE_2D_ARRAY or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02320, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions with ImplicitLod, Dref or Proj in their name, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02321, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If any VkSampler object that is accessed from a shader by the VkPipeline currently bound to VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must not be used with any of the SPIR-V OpImageSample* or OpImageSparseSample* instructions that includes a LOD bias or any offset values, in any shader stage' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02322, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02323, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'If the robust buffer access feature is not enabled, and any shader stage in the VkPipeline object currently bound to VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must not access values outside of the range of that buffer specified in the currently bound descriptor set' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02324, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_LINEAR as a result of this command must be of a format which supports linear filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02325, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must be of a format which supports cubic filtering, as specified by the VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in VkFormatProperties::linearTilingFeatures (for a linear image) or VkFormatProperties::optimalTilingFeatures(for an optimally tiled image) returned by vkGetPhysicalDeviceFormatProperties' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02326, "For more information refer to Vulkan Spec Section '26.2. Logical Operations' which states 'Any VkImageView being sampled with VK_FILTER_CUBIC_IMG as a result of this command must not have a VkImageViewType of VK_IMAGE_VIEW_TYPE_3D, VK_IMAGE_VIEW_TYPE_CUBE, or VK_IMAGE_VIEW_TYPE_CUBE_ARRAY' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDispatchIndirect)"},
+    {VALIDATION_ERROR_02327, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If the planeReorderPossible member of the VkDisplayPropertiesKHR structure returned by vkGetPhysicalDeviceDisplayPropertiesKHR for the display corresponding to displayMode is VK_TRUE then planeStackIndex must be less than the number of display planes supported by the device as determined by calling vkGetPhysicalDeviceDisplayPlanePropertiesKHR; otherwise planeStackIndex must equal the currentStackIndex member of VkDisplayPlanePropertiesKHR returned by vkGetPhysicalDeviceDisplayPlanePropertiesKHR for the display plane corresponding to displayMode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_02328, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'If alphaMode is VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR then globalAlpha must be between 0 and 1, inclusive' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_02329, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'alphaMode must be 0 or one of the bits present in the supportedAlpha member of VkDisplayPlaneCapabilitiesKHR returned by vkGetDisplayPlaneCapabilitiesKHR for the display plane corresponding to displayMode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_02330, "For more information refer to Vulkan Spec Section '29.3.2. Display Surfaces' which states 'The width and height members of imageExtent must be less than the maxImageDimensions2D member of VkPhysicalDeviceLimits' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDisplaySurfaceCreateInfoKHR)"},
+    {VALIDATION_ERROR_02331, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'minImageCount must be greater than or equal to the value returned in the minImageCount member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02332, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'minImageCount must be less than or equal to the value returned in the maxImageCount member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface if the returned maxImageCount is not zero' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02333, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageFormat and imageColorSpace must match the format and colorSpace members, respectively, of one of the VkSurfaceFormatKHR structures returned by vkGetPhysicalDeviceSurfaceFormatsKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02334, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02335, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageArrayLayers must be greater than 0 and less than or equal to the maxImageArrayLayers member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02336, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'imageUsage must be a subset of the supported usage flags present in the supportedUsageFlags member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02337, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If imageSharingMode is VK_SHARING_MODE_CONCURRENT, pQueueFamilyIndices must be a pointer to an array of queueFamilyIndexCount uint32_t values' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02338, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If imageSharingMode is VK_SHARING_MODE_CONCURRENT, queueFamilyIndexCount must be greater than 1' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02339, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'preTransform must be one of the bits present in the supportedTransforms member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02340, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'compositeAlpha must be one of the bits present in the supportedCompositeAlpha member of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02341, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'presentMode must be one of the VkPresentModeKHR values returned by vkGetPhysicalDeviceSurfacePresentModesKHR for the surface' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkSwapchainCreateInfoKHR)"},
+    {VALIDATION_ERROR_02342, "For more information refer to Vulkan Spec Section '29.6. WSI Swapchain' which states 'If more than one member of pSwapchains was created from a display surface, all display surfaces referenced that refer to the same display must use the same display mode' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkQueuePresentKHR)"},
+    {VALIDATION_ERROR_02343, "For more information refer to Vulkan Spec Section '32.1.2. Command Buffer Markers' which states 'If the matching vkCmdDebugMarkerBeginEXT command was in a secondary command buffer, the vkCmdDebugMarkerEndEXT must be in the same commandBuffer' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#vkCmdDebugMarkerEndEXT)"},
+    {VALIDATION_ERROR_02344, "For more information refer to Vulkan Spec Section '11.3. Images' which states 'If imageType is VK_IMAGE_TYPE_3D, arrayLayers must be 1.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkImageCreateInfo)"},
+    {VALIDATION_ERROR_02345, "For more information refer to Vulkan Spec Section '13.2.1. Descriptor Set Layout' which states 'The VkDescriptorSetLayoutBinding::binding members of the elements of the pBindings array must each have different values.' (https://www.khronos.org/registry/vulkan/specs/1.0-extensions/xhtml/vkspec.html#VkDescriptorSetLayoutCreateInfo)"},
+};
diff --git a/layers/vk_validation_layer_details.md b/layers/vk_validation_layer_details.md
index fdc132b..46407d0 100644
--- a/layers/vk_validation_layer_details.md
+++ b/layers/vk_validation_layer_details.md
@@ -91,6 +91,12 @@
 | Verify Memory Buffer Not Deleted | Validate Command Buffer not submitted with deleted memory buffer | INVALID_BUFFER | vkQueueSubmit | VertexBufferInvalid | None |
 | Verify Image Not Deleted | Validate Command Buffer not submitted with deleted image | INVALID_IMAGE | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
 | Verify Query Pool Not Deleted | Validate Command Buffer not submitted with deleted query pool | INVALID_QUERY_POOL | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify BufferView Not Deleted | Validate Command Buffer not submitted with deleted buffer view | INVALID_BUFFER_VIEW | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify ImageView Not Deleted | Validate Command Buffer not submitted with deleted image view | INVALID_IMAGE_VIEW | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify DescriptorPool Not Deleted | Validate Command Buffer not submitted with deleted descriptor pool | INVALID_DESCRIPTOR_POOL | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify CommandPool Not Deleted | Validate Command Buffer not submitted with deleted command pool | INVALID_COMMAND_POOL | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify Framebuffer Not Deleted | Validate Command Buffer not submitted with deleted framebuffer | INVALID_FRAMEBUFFER | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
+| Verify DeviceMemory Not Deleted | Validate Command Buffer not submitted with deleted device memory | INVALID_DEVICE_MEMORY | vkQueueSubmit | TODO | Write test (or record here if we already have one) |
 | Verify Memory Buffer Destroy | Validate memory buffers are not destroyed more than once | DOUBLE_DESTROY | vkDestroyBuffer | VertexBufferInvalid | None |
 | Verify Object Not In Use | Validate that object being freed or modified is not in use | OBJECT_INUSE | vkDestroyBuffer vkFreeDescriptorSets vkUpdateDescriptorSets vkDestroySemaphore | InUseDestroyedSignaled InvalidCmdBufferDescriptorSetImageSamplerDestroyed | NA |
 | Verify Get Queries| Validate that queries are properly setup, initialized and synchronized | INVALID_QUERY | vkGetFenceStatus vkQueueWaitIdle vkWaitForFences vkDeviceWaitIdle vkCmdBeginQuery vkCmdEndQuery | InvalidQueueIndexInvalidQuery | May need to check existing case against object_tracker and remove any redundant checks. Then write tests for remaining case. Currently there are 8 cases for this check with 1 each in cleanInFlightCmdBuffer(), EndCommandBuffer(), CmdEndQuery(), validateQuery(), and 4 cases in GetQueryPoolResults() |
@@ -103,7 +109,6 @@
 | Uniform Buffer Alignment  | Uniform Buffer offsets in BindBufferMemory, BindDescriptorSets must agree with offset alignment device limit | INVALID_UNIFORM_BUFFER_OFFSET | vkBindBufferMemory vkCmdBindDescriptorSets | VertexBufferInvalid | None |
 | Independent Blending  | If independent blending is not enabled, all elements of pAttachments must be identical | INDEPENDENT_BLEND | vkCreateGraphicsPipelines | DisabledIndependentBlend | Create test |
 | Enabled Logic Operations  | If logic operations is not enabled, logicOpEnable must be VK_FALSE | DISABLED_LOGIC_OP | vkCreateGraphicsPipelines | ColorBlendLogicOpTests | NA |
-| Valid Logic Operations  | If logicOpEnable is VK_TRUE, logicOp must be a valid VkLogicOp value | INVALID_LOGIC_OP | vkCreateGraphicsPipelines | ColorBlendLogicOpTests | NA |
 | QueueFamilyIndex is Valid | Validates that QueueFamilyIndices are less an the number of QueueFamilies | INVALID_QUEUE_INDEX | vkCmdWaitEvents vkCmdPipelineBarrier vkCreateBuffer vkCreateImage | InvalidQueueIndexInvalidQuery | NA |
 | Invalid Queue Family Consistency | Validates that items created in one Queue Family are not submitted using a different one | INVALID_QUEUE_FAMILY | vkCmdExecuteCommands vkQueueSubmit | MismatchedQueueFamiliesOnSubmit |
 | Push Constants | Validate that the size of push constant ranges and updates does not exceed maxPushConstantSize | PUSH_CONSTANTS_ERROR | vkCreatePipelineLayout vkCmdPushConstants | InvalidPushConstants | NA |
@@ -114,6 +119,11 @@
 | NA | Enum used for errors in the layer itself. This does not indicate an app issue, but instead a bug in the layer. | INTERNAL_ERROR | | TODO | None |
 | NA | Enum used when VK_LAYER_LUNARG_core_validation attempts to allocate memory for its own internal use and is unable to. | OUT_OF_MEMORY | | TODO | None |
 | Bad subpass indexing | Must not step beyond last subpass in a renderpass instance, and must reach the last subpass before CmdEndRenderPass. | INVALID_SUBPASS_INDEX | vkCmdNextSubpass | RenderPassExcessiveNextSubpass | NA |
+| Proper synchronization of acquired images | vkAcquireNextImageKHR should be called with a valid semaphore and/or fence | SWAPCHAIN_NO_SYNC_FOR_ACQUIRE | vkAcquireNextImageKHR | TODO | None |
+| Swapchain image index too large | Validates that an image index is within the number of images in a swapchain | SWAPCHAIN_INVALID_IMAGE | vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
+| Can't present a non-owned image | Validates that application only presents images that it owns | SWAPCHAIN_IMAGE_NOT_ACQUIRED | vkQueuePresentKHR | TODO | None |
+| Surface already has swapchain | Cannot create a swapchain for a surface that already has one [other than the swapchain being replaced] | SWAPCHAIN_ALREADY_EXISTS | vkCreateSwapchainKHR | TODO | None |
+| Swapchain replacement | pCreateInfo->surface must match pCreateInfo->oldSwapchain's surface | SWAPCHAIN_WRONG_SURFACE | vkCreateSwapchainKHR | TODO | None |
 
 ### VK_LAYER_LUNARG_core_validation Draw State Pending Work
 
@@ -133,15 +143,15 @@
 | Non-SPIRV shader | Flag warning if a non-SPIR-V shader image is detected. This can occur if early drivers are ingesting GLSL. VK_LAYER_LUNARG_ShaderChecker cannot analyze non-SPIRV shaders, so this suppresses most other checks. | NON_SPIRV_SHADER | vkCreateGraphicsPipelines | TODO | NA |
 | VI Binding Descriptions | Validate that there is a single vertex input binding description for each binding | INCONSISTENT_VI | vkCreateGraphicsPipelines | CreatePipelineAttribBindingConflict | NA |
 | Shader Stage Check | Warns if shader stage is unsupported | UNKNOWN_STAGE | vkCreateGraphicsPipelines | TODO | NA |
-| Shader Specialization | Error if specialization entry data is not fully contained within the specialization data block. | BAD_SPECIALIZATION | vkCreateGraphicsPipelines vkCreateComputePipelines | TODO | NA |
+| Shader Specialization | Error if specialization entry data is not fully contained within the specialization data block. | BAD_SPECIALIZATION | vkCreateGraphicsPipelines vkCreateComputePipelines | CreatePipelineCheckShaderBadSpecialization | NA |
 | Missing Descriptor | Flags error if shader attempts to use a descriptor binding not declared in the layout | MISSING_DESCRIPTOR | vkCreateGraphicsPipelines | CreatePipelineUniformBlockNotProvided | NA |
 | Missing Entrypoint | Flags error if specified entrypoint is not present in the shader module | MISSING_ENTRYPOINT | vkCreateGraphicsPipelines | TODO | NA |
 | Push constant out of range | Flags error if a member of a push constant block is not contained within a push constant range specified in the pipeline layout | PUSH_CONSTANT_OUT_OF_RANGE | vkCreateGraphicsPipelines | CreatePipelinePushConstantsNotInLayout | NA |
-| Push constant not accessible from stage | Flags error if the push constant range containing a push constant block member is not accessible from the current shader stage. | PUSH_CONSTANT_NOT_ACCESSIBLE_FROM_STAGE | vkCreateGraphicsPipelines | TODO | NA |
-| Descriptor not accessible from stage | Flags error if a descriptor used by a shader stage does not include that stage in its stageFlags | DESCRIPTOR_NOT_ACCESSIBLE_FROM_STAGE | vkCreateGraphicsPipelines | TODO | NA |
-| Descriptor type mismatch | Flags error if a descriptor type does not match the shader resource type. | DESCRIPTOR_TYPE_MISMATCH | vkCreateGraphicsPipelines | TODO | NA |
-| Feature not enabled | Flags error if a capability declared by the shader requires a feature not enabled on the device | FEATURE_NOT_ENABLED | vkCreateGraphicsPipelines | TODO | NA |
-| Bad capability | Flags error if a capability declared by the shader is not supported by Vulkan shaders | BAD_CAPABILITY | vkCreateGraphicsPipelines | TODO | NA |
+| Push constant not accessible from stage | Flags error if the push constant range containing a push constant block member is not accessible from the current shader stage. | PUSH_CONSTANT_NOT_ACCESSIBLE_FROM_STAGE | vkCreateGraphicsPipelines | CreatePipelineCheckShaderPushConstantNotAccessible | NA |
+| Descriptor not accessible from stage | Flags error if a descriptor used by a shader stage does not include that stage in its stageFlags | DESCRIPTOR_NOT_ACCESSIBLE_FROM_STAGE | vkCreateGraphicsPipelines | CreatePipelineCheckShaderDescriptorNotAccessible | NA |
+| Descriptor type mismatch | Flags error if a descriptor type does not match the shader resource type. | DESCRIPTOR_TYPE_MISMATCH | vkCreateGraphicsPipelines | CreatePipelineCheckShaderDescriptorTypeMismatch | NA |
+| Feature not enabled | Flags error if a capability declared by the shader requires a feature not enabled on the device | FEATURE_NOT_ENABLED | vkCreateGraphicsPipelines | CreatePipelineCheckShaderNotEnabled | NA |
+| Bad capability | Flags error if a capability declared by the shader is not supported by Vulkan shaders | BAD_CAPABILITY | vkCreateGraphicsPipelines | CreatePipelineCheckShaderBadCapability | NA |
 | Missing input attachment | Flags error if shader consumes an input attachment which is not provided in the subpass in which a pipeline will be used | MISSING_INPUT_ATTACHMENT | vkCreateGraphicsPipelines | CreatePipelineInputAttachment* | NA |
 | Input attachment type mismatch | Flags error if shader's declaration of an input attachment has a type inconsistent with the format declared in the renderpass | INPUT_ATTACHMENT_TYPE_MISMATCH | vkCreateGraphicsPipelines | CreatePipelineInputAttachmentTypeMismatch | NA |
 | NA | Enum used for informational messages | NONE | | TODO | None |
@@ -231,7 +241,7 @@
 | ----- | -------- | ---------------- | ------------ | -------- | ---------- |
 | Image Format | Verifies that requested format is a supported Vulkan format on this device | FORMAT_UNSUPPORTED | vkCreateImage vkCreateRenderPass | ImageLayerUnsupportedFormat | NA |
 | RenderPass Attachments | Validates that attachment image format, layouts, loadOps, and storeOps are valid Vulkan values | RENDERPASS_INVALID_ATTACHMENT | vkCreateRenderPass | AttachmentDescriptionUndefinedFormat | Tests are needed for loadops, storeops, layouts, and bad depth format |
-| Subpass DS Settings | Verifies that if there is no depth attachment then the subpass attachment is set to VK_ATTACHMENT_UNUSED | RENDERPASS_INVALID_DS_ATTACHMENT | vkCreateRenderPass | RenderPassDepthStencilAttachmentUnused | NA |
+| Subpass Depth/Stencil Settings | Verifies that if there is no depth/stencil attachment then the subpass attachment is set to VK_ATTACHMENT_UNUSED | RENDERPASS_INVALID_DS_ATTACHMENT | vkCreateRenderPass | RenderPassDepthStencilAttachmentUnused | NA |
 | View Creation | Verify that requested Image View Creation parameters are reasonable for the image that the view is being created for | VIEW_CREATE_ERROR | vkCreateImageView | ImageLayerViewTests | NA |
 | Image Aspects | Verify that Image commands are using valid Image Aspect flags | INVALID_IMAGE_ASPECT | vkCreateImageView vkCmdClearColorImage vkCmdClearDepthStencilImage vkCmdClearAttachments vkCmdCopyImage vkCmdCopyImageToBuffer vkCmdCopyBufferToImage vkCmdResolveImage vkCmdBlitImage | InvalidImageViewAspect | NA |
 | Image Aspect Mismatch | Verify that Image commands with source and dest images use matching aspect flags | MISMATCHED_IMAGE_ASPECT | vkCmdCopyImage | MiscImageLayerTests | NA |
@@ -266,6 +276,7 @@
 | Unknown object  | Internal layer errors when it attempts to update use count for an object that's not in its internal tracking datastructures. | UNKNOWN_OBJECT |  | CreateUnknownObject | NA |
 | Correct Command Pool | Validates that command buffers in a FreeCommandBuffers call were all created in the specified commandPool | COMMAND_POOL_MISMATCH | vkFreeCommandBuffers | InvalidCommandPoolConsistency | NA |
 | Correct Descriptor Pool | Validates that descriptor sets in a FreeDescriptorSets call were all created in the specified descriptorPool | DESCRIPTOR_POOL_MISMATCH | vkFreeDescriptorSets | InvalidDescriptorPoolConsistency | NA |
+| Inconsistent Allocators | Validates that a custom allocator is either provided for both create and destroy, or neither. | ALLOCATOR_MISMATCH | | TODO | None |
 | NA | Enum used for informational messages | NONE | | TODO | None |
 | NA | Enum used for errors in the layer itself. This does not indicate an app issue, but instead a bug in the layer. | INTERNAL_ERROR | | TODO | None |
 
@@ -339,22 +350,16 @@
 | vkCreateSwapchainKHR(pCreateInfo->presentMode) | Validates vkCreateSwapchainKHR(pCreateInfo->presentMode) | CREATE_SWAP_BAD_PRESENT_MODE | vkCreateSwapchainKHR | TODO | None |
 | vkCreateSwapchainKHR(pCreateInfo->imageSharingMode) | Validates vkCreateSwapchainKHR(pCreateInfo->imageSharingMode) | CREATE_SWAP_BAD_SHARING_MODE | vkCreateSwapchainKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
 | vkCreateSwapchainKHR(pCreateInfo->imageSharingMode) | Validates vkCreateSwapchainKHR(pCreateInfo->imageSharingMode) | CREATE_SWAP_BAD_SHARING_VALUES | vkCreateSwapchainKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
-| vkCreateSwapchainKHR(pCreateInfo->oldSwapchain and pCreateInfo->surface) | pCreateInfo->surface must match pCreateInfo->oldSwapchain's surface | CREATE_SWAP_DIFF_SURFACE | vkCreateSwapchainKHR | TODO | None |
-| Use same device for swapchain | Validates that vkDestroySwapchainKHR() called with the same VkDevice as vkCreateSwapchainKHR() | DESTROY_SWAP_DIFF_DEVICE | vkCreateSwapchainKHR vkDestroySwapchainKHR | TODO | None |
 | Don't acquire too many images | Validates that app never tries to acquire too many swapchain images at a time | APP_ACQUIRES_TOO_MANY_IMAGES | vkAcquireNextImageKHR | TODO | None |
-| Index too large | Validates that an image index is within the number of images in a swapchain | INDEX_TOO_LARGE | vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
-| Can't present a non-owned image | Validates that application only presents images that it owns | INDEX_NOT_IN_USE | vkQueuePresentKHR | TODO | None |
 | A VkBool32 must have values of VK_TRUE or VK_FALSE | Validates that a VkBool32 must have values of VK_TRUE or VK_FALSE | BAD_BOOL | vkCreateSwapchainKHR | TODO | None |
 | pCount must be set by the API before the other pointer is non-NULL | Validates that app queries for the value of pCount before trying to set it | PRIOR_COUNT | vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkGetSwapchainImagesKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
 | pCount must point to same value regardless of whether other pointer is NULL | Validates that app doesn't change value of pCount returned by a query | INVALID_COUNT | vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfacePresentModesKHR vkGetSwapchainImagesKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
 | Valid sType | Validates that a struct has correct value for sType | WRONG_STYPE | vkCreateSwapchainKHR vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
 | Valid pNext | Validates that a struct has NULL for the value of pNext | WRONG_NEXT | vkCreateSwapchainKHR vkQueuePresentKHR | VkWsiEnabledLayerTest.TestEnabledWsi | None |
 | Non-zero value | Validates that a required value should be non-zero | ZERO_VALUE | vkQueuePresentKHR | TODO | None |
-| Compatible Allocator | Validates that pAllocator is compatible (i.e. NULL or not) when an object is created and destroyed | INCOMPATIBLE_ALLOCATOR | vkDestroySurfaceKHR | TODO | None |
 | Valid use of queueFamilyIndex | Validates that a queueFamilyIndex not used before vkGetPhysicalDeviceQueueFamilyProperties() was called | DID_NOT_QUERY_QUEUE_FAMILIES | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | None |
 | Valid queueFamilyIndex value | Validates that a queueFamilyIndex value is less-than pQueueFamilyPropertyCount returned by vkGetPhysicalDeviceQueueFamilyProperties | QUEUE_FAMILY_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | None |
 | Supported combination of queue and surface | Validates that the surface associated with a swapchain was seen to support the queueFamilyIndex of a given queue | SURFACE_NOT_SUPPORTED_WITH_QUEUE | vkQueuePresentKHR | TODO | None |
-| Proper synchronization of acquired images | vkAcquireNextImageKHR should be called with a valid semaphore and/or fence | NO_SYNC_FOR_ACQUIRE | vkAcquireNextImageKHR | TODO | None |
 | Potential use before query | Validates that Display Plane Properties are queried before getting supported Display Planes | GET_SUPPORTED_DISPLAYS_WITHOUT_QUERY | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneSupportedDisplaysKHR |
 | Index too large | Validates index is in range of phys device display plane props | PLANE_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneSupportedDisplaysKHR |
 | Index too large | Validates index is in range of phys device display plane props | PLANE_INDEX_TOO_LARGE | vkGetPhysicalDeviceSurfaceSupportKHR | TODO | actually: vkGetDisplayPlaneCapabilitiesKHR |
diff --git a/layers/windows/VkLayer_core_validation.json b/layers/windows/VkLayer_core_validation.json
index b7c0164..8f731aa 100644
--- a/layers/windows/VkLayer_core_validation.json
+++ b/layers/windows/VkLayer_core_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_core_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_core_validation.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_image.json b/layers/windows/VkLayer_image.json
index 0213c8d..8f4fe64 100644
--- a/layers/windows/VkLayer_image.json
+++ b/layers/windows/VkLayer_image.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_image",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_image.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_object_tracker.json b/layers/windows/VkLayer_object_tracker.json
index 56413e5..408aebf 100644
--- a/layers/windows/VkLayer_object_tracker.json
+++ b/layers/windows/VkLayer_object_tracker.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_object_tracker",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_object_tracker.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_parameter_validation.json b/layers/windows/VkLayer_parameter_validation.json
index 019b931..f079958 100644
--- a/layers/windows/VkLayer_parameter_validation.json
+++ b/layers/windows/VkLayer_parameter_validation.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_parameter_validation",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_parameter_validation.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_swapchain.json b/layers/windows/VkLayer_swapchain.json
index f6eb021..ea98c9c 100644
--- a/layers/windows/VkLayer_swapchain.json
+++ b/layers/windows/VkLayer_swapchain.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_LUNARG_swapchain",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_swapchain.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "LunarG Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_threading.json b/layers/windows/VkLayer_threading.json
index d22bdcd..e30cfff 100644
--- a/layers/windows/VkLayer_threading.json
+++ b/layers/windows/VkLayer_threading.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_threading",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_threading.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "Google Validation Layer",
         "instance_extensions": [
diff --git a/layers/windows/VkLayer_unique_objects.json b/layers/windows/VkLayer_unique_objects.json
index 05be9d0..6616aa4 100644
--- a/layers/windows/VkLayer_unique_objects.json
+++ b/layers/windows/VkLayer_unique_objects.json
@@ -4,7 +4,7 @@
         "name": "VK_LAYER_GOOGLE_unique_objects",
         "type": "GLOBAL",
         "library_path": ".\\VkLayer_unique_objects.dll",
-        "api_version": "1.0.26",
+        "api_version": "1.0.31",
         "implementation_version": "1",
         "description": "Google Validation Layer"
     }
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 2758bfc..793dccc 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -61,7 +61,6 @@
     add_library(loader-opt OBJECT ${OPT_LOADER_SRCS})
     target_compile_options(loader-opt PUBLIC "$<$<CONFIG:DEBUG>:${LOCAL_C_FLAGS_REL}>")
     add_library(vulkan-${MAJOR} SHARED $<TARGET_OBJECTS:loader-opt> $<TARGET_OBJECTS:loader-norm> ${CMAKE_CURRENT_BINARY_DIR}/vulkan-${MAJOR}.def ${CMAKE_CURRENT_SOURCE_DIR}/loader.rc)
-    set_target_properties(vulkan-${MAJOR} PROPERTIES LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/vulkan-${MAJOR}.def")
     add_library(VKstatic.${MAJOR} STATIC $<TARGET_OBJECTS:loader-opt> $<TARGET_OBJECTS:loader-norm>)
     set_target_properties(VKstatic.${MAJOR} PROPERTIES OUTPUT_NAME VKstatic.${MAJOR})
     target_link_libraries(vulkan-${MAJOR} shlwapi)
@@ -84,6 +83,7 @@
     set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith")
 
     add_library(vulkan SHARED ${LOADER_SRCS})
-    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.26")
+    set_target_properties(vulkan PROPERTIES SOVERSION "1" VERSION "1.0.31")
     target_link_libraries(vulkan -ldl -lpthread -lm)
+    install(TARGETS vulkan LIBRARY DESTINATION lib)
 endif()
diff --git a/loader/LoaderAndLayerInterface.md b/loader/LoaderAndLayerInterface.md
index 22d5520..b559941 100644
--- a/loader/LoaderAndLayerInterface.md
+++ b/loader/LoaderAndLayerInterface.md
@@ -155,7 +155,7 @@
 just link to the name vulkan (libvulkan.so).  A specific Vulkan ABI version can
 also be linked to by applications (e.g. libvulkan.so.1).
 
-####Layer Usage
+#### Layer Usage
 
 Applications desiring Vulkan functionality beyond what the core API offers may
 use various layers or extensions. A layer cannot introduce new Vulkan API
@@ -592,7 +592,7 @@
 
 ##### Version Negotiation Between Loader and ICDs
 
-All ICDs  (supporting interface version 2 or higher) must export the following
+All ICDs (supporting interface version 2 or higher) must export the following
 function that is used for determination of the interface version that will be used.
 This entry point is not a part of the Vulkan API itself, only a private interface
 between the loader and ICDs.
@@ -633,11 +633,31 @@
 and will not load it for use.  In this case the application will not see the ICDs vkPhysicalDevice
 during enumeration.
 
+##### Loader Version 3 Interface Changes
+
+The primary change occuring in version 3 of the loader/ICD interface is to allow an ICD to
+handle Creation/Destruction of their own KHR_surfaces.  Up until this point, the loader created
+a surface object that was used by all ICDs.  However, some ICDs may want to provide their
+own surface handles.  If an ICD chooses to enable this support, they must export support for
+version 3 of the Loader/ICD interface as well as any Vulkan command that uses a KHR_surface handle,
+such as:
+- vkCreateXXXSurfaceKHR (where XXX is the platform specific identifier [i.e.CreateWin32SurfaceKHR for Windows])
+- vkDestroySurfaceKHR
+- vkCreateSwapchainKHR
+- vkGetPhysicalDeviceSurfaceSupportKHR
+- vkGetPhysicalDeviceSurfaceCapabilitiesKHR
+- vkGetPhysicalDeviceSurfaceFormatsKHR
+- vkGetPhysicalDeviceSurfacePresentModesKHR
+
+An ICD can still choose to not take advantage of this functionality by simply not exposing the
+above the vkCreateXXXSurfaceKHR and vkDestroySurfaceKHR commands.
+
 ##### Loader Version 2 Interface Requirements
 
-Version 2 interface has requirements in three areas: 1) ICD Vulkan entry point discovery,
-2) KHR_surface related requirements in the WSI extensions, 3) Vulkan dispatchable object
-creation requirements.
+Version 2 interface has requirements in three areas:
+ 1. ICD Vulkan entry point discovery,
+ 2. KHR_surface related requirements in the WSI extensions,
+ 3. Vulkan dispatchable object creation requirements.
 
 ######  ICD Vulkan entry point discovery
 All ICDs must export the following function that is used for discovery of ICD Vulkan entry points.
diff --git a/loader/debug_report.c b/loader/debug_report.c
index 667ef47..4054d4e 100644
--- a/loader/debug_report.c
+++ b/loader/debug_report.c
@@ -308,7 +308,7 @@
     VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,
     const VkAllocationCallbacks *pAllocator,
     VkDebugReportCallbackEXT *pCallback) {
-    VkDebugReportCallbackEXT *icd_info;
+    VkDebugReportCallbackEXT *icd_info = NULL;
     const struct loader_icd *icd;
     struct loader_instance *inst = (struct loader_instance *)instance;
     VkResult res = VK_SUCCESS;
@@ -331,7 +331,8 @@
             calloc(sizeof(VkDebugReportCallbackEXT), inst->total_icd_count);
     }
     if (!icd_info) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
     storage_idx = 0;
@@ -344,7 +345,7 @@
             icd->instance, pCreateInfo, pAllocator, &icd_info[storage_idx]);
 
         if (res != VK_SUCCESS) {
-            break;
+            goto out;
         }
         storage_idx++;
     }
@@ -368,19 +369,24 @@
                 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     }
     if (!pNewDbgFuncNode) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        res = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
     memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
 
-    pNewDbgFuncNode->msgCallback = *pCallback;
     pNewDbgFuncNode->pfnMsgCallback = pCreateInfo->pfnCallback;
     pNewDbgFuncNode->msgFlags = pCreateInfo->flags;
     pNewDbgFuncNode->pUserData = pCreateInfo->pUserData;
     pNewDbgFuncNode->pNext = inst->DbgFunctionHead;
     inst->DbgFunctionHead = pNewDbgFuncNode;
 
-    /* roll back on errors */
-    if (icd) {
+    *(VkDebugReportCallbackEXT **)pCallback = icd_info;
+    pNewDbgFuncNode->msgCallback = *pCallback;
+
+out:
+
+    // Roll back on errors
+    if (VK_SUCCESS != res) {
         storage_idx = 0;
         for (icd = inst->icds; icd; icd = icd->next) {
             if (NULL == icd->DestroyDebugReportCallbackEXT) {
@@ -394,12 +400,28 @@
             storage_idx++;
         }
 
-        return res;
+#if (DEBUG_DISABLE_APP_ALLOCATORS == 1)
+        {
+#else
+        if (pAllocator != NULL) {
+            if (NULL != pNewDbgFuncNode) {
+                pAllocator->pfnFree(pAllocator->pUserData, pNewDbgFuncNode);
+            }
+            if (NULL != icd_info) {
+                pAllocator->pfnFree(pAllocator->pUserData, icd_info);
+            }
+        } else {
+#endif
+            if (NULL != pNewDbgFuncNode) {
+                free(pNewDbgFuncNode);
+            }
+            if (NULL != icd_info) {
+                free(icd_info);
+            }
+        }
     }
 
-    *(VkDebugReportCallbackEXT **)pCallback = icd_info;
-
-    return VK_SUCCESS;
+    return res;
 }
 
 /*
diff --git a/loader/loader.c b/loader/loader.c
index 9323cff..184809b 100644
--- a/loader/loader.c
+++ b/loader/loader.c
@@ -412,7 +412,7 @@
 VKAPI_ATTR VkResult VKAPI_CALL
 vkSetDeviceDispatch(VkDevice device, void *object) {
     struct loader_device *dev;
-    struct loader_icd *icd = loader_get_icd_and_device(device, &dev);
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, NULL);
 
     if (!icd) {
         return VK_ERROR_INITIALIZATION_FAILED;
@@ -824,12 +824,14 @@
                                                NULL);
     if (res == VK_SUCCESS && count > 0) {
         ext_props = loader_stack_alloc(count * sizeof(VkExtensionProperties));
-        if (!ext_props)
+        if (!ext_props) {
             return VK_ERROR_OUT_OF_HOST_MEMORY;
+        }
         res = fpEnumerateDeviceExtensionProperties(physical_device, NULL,
                                                    &count, ext_props);
-        if (res != VK_SUCCESS)
+        if (res != VK_SUCCESS) {
             return res;
+        }
         for (i = 0; i < count; i++) {
             char spec_version[64];
 
@@ -1243,8 +1245,10 @@
 }
 
 struct loader_icd *loader_get_icd_and_device(const VkDevice device,
-                                             struct loader_device **found_dev) {
+                                             struct loader_device **found_dev,
+                                             uint32_t *icd_index) {
     *found_dev = NULL;
+    uint32_t index = 0;
     for (struct loader_instance *inst = loader.instances; inst;
          inst = inst->next) {
         for (struct loader_icd *icd = inst->icds; icd; icd = icd->next) {
@@ -1255,8 +1259,12 @@
                 if (loader_get_dispatch(dev->device) ==
                     loader_get_dispatch(device)) {
                     *found_dev = dev;
+                    if (NULL != icd_index) {
+                        *icd_index = index;
+                    }
                     return icd;
                 }
+            index++;
         }
     }
     return NULL;
@@ -1634,16 +1642,25 @@
     LOOKUP_GIPA(CreateDisplayModeKHR, false);
     LOOKUP_GIPA(GetDisplayPlaneCapabilitiesKHR, false);
     LOOKUP_GIPA(DestroySurfaceKHR, false);
+    LOOKUP_GIPA(CreateSwapchainKHR, false);
 #ifdef VK_USE_PLATFORM_WIN32_KHR
+    LOOKUP_GIPA(CreateWin32SurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceWin32PresentationSupportKHR, false);
 #endif
 #ifdef VK_USE_PLATFORM_XCB_KHR
+    LOOKUP_GIPA(CreateXcbSurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceXcbPresentationSupportKHR, false);
 #endif
 #ifdef VK_USE_PLATFORM_XLIB_KHR
+    LOOKUP_GIPA(CreateXlibSurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceXlibPresentationSupportKHR, false);
 #endif
+#ifdef VK_USE_PLATFORM_MIR_KHR
+    LOOKUP_GIPA(CreateMirSurfaceKHR, false);
+    LOOKUP_GIPA(GetPhysicalDeviceMirPresentationSupportKHR, false);
+#endif
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    LOOKUP_GIPA(CreateWaylandSurfaceKHR, false);
     LOOKUP_GIPA(GetPhysicalDeviceWaylandPresentationSupportKHR, false);
 #endif
     LOOKUP_GIPA(GetPhysicalDeviceExternalImageFormatPropertiesNV, false);
@@ -3232,10 +3249,36 @@
     return NULL;
 }
 
-static VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+void loader_override_terminating_device_proc(
+    VkDevice device, struct loader_dev_dispatch_table *disp_table) {
+    struct loader_device *dev;
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, NULL);
+
+    // Certain device entry-points still need to go through a terminator before
+    // hitting the ICD.  This could be for several reasons, but the main one
+    // is currently unwrapping an object before passing the appropriate info
+    // along to the ICD.
+    if ((PFN_vkVoidFunction)disp_table->core_dispatch.CreateSwapchainKHR ==
+        (PFN_vkVoidFunction)icd->GetDeviceProcAddr(device,
+                                                   "vkCreateSwapchainKHR")) {
+        disp_table->core_dispatch.CreateSwapchainKHR =
+            terminator_vkCreateSwapchainKHR;
+    }
+}
+
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
 loader_gpa_device_internal(VkDevice device, const char *pName) {
     struct loader_device *dev;
-    struct loader_icd *icd = loader_get_icd_and_device(device, &dev);
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, NULL);
+
+    // Certain device entry-points still need to go through a terminator before
+    // hitting the ICD.  This could be for several reasons, but the main one
+    // is currently unwrapping an object before passing the appropriate info
+    // along to the ICD.
+    if (!strcmp(pName, "vkCreateSwapchainKHR")) {
+        return (PFN_vkVoidFunction)terminator_vkCreateSwapchainKHR;
+    }
+
     return icd->GetDeviceProcAddr(device, pName);
 }
 
@@ -3330,17 +3373,6 @@
     return false;
 }
 
-static bool
-loader_check_layers_for_address(const struct loader_instance *const inst,
-                                const char *funcName) {
-    if (loader_check_layer_list_for_address(&inst->instance_layer_list,
-                                            funcName)) {
-        return true;
-    }
-
-    return false;
-}
-
 static void loader_free_dev_ext_table(struct loader_instance *inst) {
     for (uint32_t i = 0; i < MAX_NUM_DEV_EXTS; i++) {
         loader_instance_heap_free(inst, inst->disp_hash[i].func_name);
@@ -3473,7 +3505,7 @@
 
     // Check if funcName is supported in either ICDs or a layer library
     if (!loader_check_icds_for_address(inst, funcName) &&
-        !loader_check_layers_for_address(inst, funcName)) {
+        !loader_check_layer_list_for_address(&inst->instance_layer_list, funcName)) {
         // if support found in layers continue on
         return NULL;
     }
@@ -3994,7 +4026,7 @@
         /* Not in global list, search layer extension lists */
         for (uint32_t j = 0; j < pCreateInfo->enabledLayerCount; j++) {
             layer_prop = loader_get_layer_property(
-                pCreateInfo->ppEnabledLayerNames[i], instance_layer);
+                pCreateInfo->ppEnabledLayerNames[j], instance_layer);
             if (!layer_prop) {
                 /* Should NOT get here, loader_validate_layers
                  * should have already filtered this case out.
@@ -4272,6 +4304,10 @@
     icd_exts.list = NULL;
 
     if (fpCreateDevice == NULL) {
+        loader_log(phys_dev->this_icd->this_instance,
+                   VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "No vkCreateDevice command exposed by ICD %s",
+                   phys_dev->this_icd->this_icd_lib->lib_name);
         res = VK_ERROR_INITIALIZATION_FAILED;
         goto out;
     }
@@ -4325,17 +4361,23 @@
             filtered_extension_names[localCreateInfo.enabledExtensionCount] =
                 (char *)extension_name;
             localCreateInfo.enabledExtensionCount++;
+        } else {
+            loader_log(phys_dev->this_icd->this_instance,
+                       VK_DEBUG_REPORT_WARNING_BIT_EXT, 0,
+                       "vkCreateDevice extension %s not available for "
+                       "devices associated with ICD %s",
+                       extension_name,
+                       phys_dev->this_icd->this_icd_lib->lib_name);
         }
     }
 
-    // TODO: Why does fpCreateDevice behave differently than
-    // this_icd->CreateDevice?
-    //    VkResult res = fpCreateDevice(phys_dev->phys_dev, &localCreateInfo,
-    //    pAllocator, &localDevice);
-    res = phys_dev->this_icd->CreateDevice(phys_dev->phys_dev, &localCreateInfo,
-                                           pAllocator, &dev->device);
-
+    res = fpCreateDevice(phys_dev->phys_dev, &localCreateInfo, pAllocator,
+                         &dev->device);
     if (res != VK_SUCCESS) {
+        loader_log(phys_dev->this_icd->this_instance,
+                   VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
+                   "vkCreateDevice call failed in ICD %s",
+                   phys_dev->this_icd->this_icd_lib->lib_name);
         goto out;
     }
 
@@ -4401,48 +4443,55 @@
         icd = icd->next;
     }
 
-    *pPhysicalDeviceCount = inst->total_gpu_count;
-    if (!pPhysicalDevices) {
-        return res;
-    }
+    uint32_t copy_count = inst->total_gpu_count;
 
-    /* Initialize the output pPhysicalDevices  with wrapped loader terminator
-     * physicalDevice objects; save this list of wrapped objects in instance
-     * struct for later cleanup and use by trampoline code */
-    uint32_t j, idx = 0;
-    uint32_t copy_count = 0;
+    if (NULL != pPhysicalDevices) {
+        // Initialize the output pPhysicalDevices with wrapped loader
+        // terminator physicalDevice objects; save this list of
+        // wrapped objects in instance struct for later cleanup and
+        // use by trampoline code
+        uint32_t j, idx = 0;
 
-    copy_count = (inst->total_gpu_count < *pPhysicalDeviceCount)
-                     ? inst->total_gpu_count
-                     : *pPhysicalDeviceCount;
+        if (copy_count > *pPhysicalDeviceCount) {
+            copy_count = *pPhysicalDeviceCount;
+        }
 
-    if (inst->phys_devs_term)
-        loader_instance_heap_free(inst, inst->phys_devs_term);
-    inst->phys_devs_term = loader_instance_heap_alloc(
-        inst, sizeof(struct loader_physical_device) * copy_count,
-        VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
-    if (!inst->phys_devs_term)
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        if (inst->phys_devs_term) {
+            loader_instance_heap_free(inst, inst->phys_devs_term);
+            inst->phys_devs_term = NULL;
+        }
 
-    for (i = 0; idx < copy_count && i < inst->total_icd_count; i++) {
+        if (inst->total_gpu_count > 0) {
+            inst->phys_devs_term = loader_instance_heap_alloc(
+                inst, sizeof(struct loader_physical_device) * inst->total_gpu_count,
+                VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+            if (!inst->phys_devs_term) {
+                return VK_ERROR_OUT_OF_HOST_MEMORY;
+            }
+        }
 
-        for (j = 0; j < phys_devs[i].count && idx < copy_count; j++) {
-            loader_set_dispatch((void *)&inst->phys_devs_term[idx], inst->disp);
-            inst->phys_devs_term[idx].this_icd = phys_devs[i].this_icd;
-            inst->phys_devs_term[idx].phys_dev = phys_devs[i].phys_devs[j];
-            pPhysicalDevices[idx] =
-                (VkPhysicalDevice)&inst->phys_devs_term[idx];
-            idx++;
+        for (i = 0; idx < inst->total_gpu_count && i < inst->total_icd_count; i++) {
+            for (j = 0; j < phys_devs[i].count && idx < inst->total_gpu_count; j++) {
+                loader_set_dispatch((void *)&inst->phys_devs_term[idx],
+                                    inst->disp);
+                inst->phys_devs_term[idx].this_icd = phys_devs[i].this_icd;
+                inst->phys_devs_term[idx].icd_index = (uint8_t)(i);
+                inst->phys_devs_term[idx].phys_dev = phys_devs[i].phys_devs[j];
+                if (idx < copy_count) {
+                    pPhysicalDevices[idx] =
+                        (VkPhysicalDevice)&inst->phys_devs_term[idx];
+                }
+                idx++;
+            }
+        }
+
+        if (copy_count < inst->total_gpu_count) {
+            res = VK_INCOMPLETE;
         }
     }
+
     *pPhysicalDeviceCount = copy_count;
 
-    // TODO: Is phys_devs being leaked?
-
-    if (copy_count < inst->total_gpu_count) {
-        inst->total_gpu_count = copy_count;
-        return VK_INCOMPLETE;
-    }
     return res;
 }
 
diff --git a/loader/loader.h b/loader/loader.h
index 19d28e1..5eb56d9 100644
--- a/loader/loader.h
+++ b/loader/loader.h
@@ -209,22 +209,27 @@
     PFN_vkGetPhysicalDeviceExternalImageFormatPropertiesNV
         GetPhysicalDeviceExternalImageFormatPropertiesNV;
 #ifdef VK_USE_PLATFORM_WIN32_KHR
+    PFN_vkCreateWin32SurfaceKHR CreateWin32SurfaceKHR;
     PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR
         GetPhysicalDeviceWin32PresentationSupportKHR;
 #endif
 #ifdef VK_USE_PLATFORM_MIR_KHR
+    PFN_vkCreateMirSurfaceKHR CreateMirSurfaceKHR;
     PFN_vkGetPhysicalDeviceMirPresentationSupportKHR
         GetPhysicalDeviceMirPresentationSupportKHR;
 #endif
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
+    PFN_vkCreateWaylandSurfaceKHR CreateWaylandSurfaceKHR;
     PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
         GetPhysicalDeviceWaylandPresentationSupportKHR;
 #endif
 #ifdef VK_USE_PLATFORM_XCB_KHR
+    PFN_vkCreateXcbSurfaceKHR CreateXcbSurfaceKHR;
     PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR
         GetPhysicalDeviceXcbPresentationSupportKHR;
 #endif
 #ifdef VK_USE_PLATFORM_XLIB_KHR
+    PFN_vkCreateXlibSurfaceKHR CreateXlibSurfaceKHR;
     PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR
         GetPhysicalDeviceXlibPresentationSupportKHR;
 #endif
@@ -239,6 +244,7 @@
     PFN_vkGetDisplayPlaneCapabilitiesKHR GetDisplayPlaneCapabilitiesKHR;
     PFN_vkCreateDisplayPlaneSurfaceKHR CreateDisplayPlaneSurfaceKHR;
     PFN_vkDestroySurfaceKHR DestroySurfaceKHR;
+    PFN_vkCreateSwapchainKHR CreateSwapchainKHR;
     struct loader_icd *next;
 };
 
@@ -333,6 +339,7 @@
 struct loader_physical_device {
     VkLayerInstanceDispatchTable *disp; // must be first entry in structure
     struct loader_icd *this_icd;
+    uint8_t icd_index;
     VkPhysicalDevice phys_dev; // object from ICD
 };
 
@@ -500,11 +507,13 @@
     const struct loader_instance *inst, struct loader_icd_libs *icd_libs,
     struct loader_extension_list *inst_exts);
 struct loader_icd *loader_get_icd_and_device(const VkDevice device,
-                                             struct loader_device **found_dev);
+                                             struct loader_device **found_dev,
+                                             uint32_t *icd_index);
 void loader_init_dispatch_dev_ext(struct loader_instance *inst,
                                   struct loader_device *dev);
 void *loader_dev_ext_gpa(struct loader_instance *inst, const char *funcName);
 void *loader_get_dev_ext_trampoline(uint32_t index);
+void loader_override_terminating_device_proc(VkDevice device, struct loader_dev_dispatch_table *disp_table);
 struct loader_instance *loader_get_instance(const VkInstance instance);
 void loader_deactivate_layers(const struct loader_instance *instance,
                               struct loader_device *device,
diff --git a/loader/table_ops.h b/loader/table_ops.h
index cb84b87..546273f 100644
--- a/loader/table_ops.h
+++ b/loader/table_ops.h
@@ -31,7 +31,7 @@
 
 static VkResult vkDevExtError(VkDevice dev) {
     struct loader_device *found_dev;
-    struct loader_icd *icd = loader_get_icd_and_device(dev, &found_dev);
+    struct loader_icd *icd = loader_get_icd_and_device(dev, &found_dev, NULL);
 
     if (icd)
         loader_log(icd->this_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -540,6 +540,20 @@
     if (!strcmp(name, "CmdExecuteCommands"))
         return (void *)table->CmdExecuteCommands;
 
+    if (!strcmp(name, "CreateSwapchainKHR")) {
+        // For CreateSwapChainKHR we need to use trampoline and terminator
+        // functions to properly unwrap the SurfaceKHR object.
+        return (void *)vkCreateSwapchainKHR;
+    }
+    if (!strcmp(name, "DestroySwapchainKHR"))
+        return (void *)table->DestroySwapchainKHR;
+    if (!strcmp(name, "GetSwapchainImagesKHR"))
+        return (void *)table->GetSwapchainImagesKHR;
+    if (!strcmp(name, "AcquireNextImageKHR"))
+        return (void *)table->AcquireNextImageKHR;
+    if (!strcmp(name, "QueuePresentKHR"))
+        return (void *)table->QueuePresentKHR;
+
     return NULL;
 }
 
diff --git a/loader/trampoline.c b/loader/trampoline.c
index 7ed168f..81513f9 100644
--- a/loader/trampoline.c
+++ b/loader/trampoline.c
@@ -713,16 +713,21 @@
 
     *pDevice = dev->device;
 
-    /* initialize any device extension dispatch entry's from the instance list*/
+    // Initialize any device extension dispatch entry's from the instance list
     loader_init_dispatch_dev_ext(inst, dev);
 
-    /* initialize WSI device extensions as part of core dispatch since loader
-     * has
-     * dedicated trampoline code for these*/
+    // Initialize WSI device extensions as part of core dispatch since loader
+    // has dedicated trampoline code for these*/
     loader_init_device_extension_dispatch_table(
         &dev->loader_dispatch,
         dev->loader_dispatch.core_dispatch.GetDeviceProcAddr, *pDevice);
 
+    // The loader needs to override some terminating device procs.  Usually,
+    // these are device procs which need to go through a loader terminator.
+    // This needs to occur if the loader needs to perform some work prior
+    // to passing the work along to the ICD.
+    loader_override_terminating_device_proc(*pDevice, &dev->loader_dispatch);
+
 out:
 
     // Failure cleanup
@@ -751,7 +756,7 @@
 
     loader_platform_thread_lock_mutex(&loader_lock);
 
-    struct loader_icd *icd = loader_get_icd_and_device(device, &dev);
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, NULL);
     const struct loader_instance *inst = icd->this_instance;
     disp = loader_get_dispatch(device);
 
diff --git a/loader/vk-loader-generate.py b/loader/vk-loader-generate.py
index 1be9898..6df17b9 100755
--- a/loader/vk-loader-generate.py
+++ b/loader/vk-loader-generate.py
@@ -115,127 +115,6 @@
     def generate_footer(self):
         pass
 
-class DevExtTrampolineSubcommand(Subcommand):
-    def generate_header(self):
-        lines = []
-        lines.append("#include \"vk_loader_platform.h\"")
-        lines.append("#include \"loader.h\"")
-        lines.append("#if defined(__linux__)")
-        lines.append("#pragma GCC optimize(3)  // force gcc to use tail-calls")
-        lines.append("#endif")
-        return "\n".join(lines)
-
-    def generate_body(self):
-        lines = []
-        for i in range(250):
-            lines.append('\nVKAPI_ATTR void VKAPI_CALL vkDevExt%s(VkDevice device)' % i)
-            lines.append('{')
-            lines.append('    const struct loader_dev_dispatch_table *disp;')
-            lines.append('    disp = loader_get_dev_dispatch(device);')
-            lines.append('    disp->ext_dispatch.DevExt[%s](device);' % i)
-            lines.append('}')
-        lines.append('')
-        lines.append('void *loader_get_dev_ext_trampoline(uint32_t index)')
-        lines.append('{')
-        lines.append('    switch (index) {')
-        for i in range(250):
-            lines.append('        case %s:' % i)
-            lines.append('            return vkDevExt%s;' % i)
-        lines.append('    }')
-        lines.append('    return NULL;')
-        lines.append('}')
-        return "\n".join(lines)
-
-class LoaderEntrypointsSubcommand(Subcommand):
-    def generate_header(self):
-        return "#include \"loader.h\""
-
-    def _generate_object_setup(self, proto):
-        method = "loader_init_dispatch"
-        cond = "res == VK_SUCCESS"
-        setup = []
-
-        if not self._requires_special_trampoline_code(proto.name):
-           return setup
-
-        if "Get" in proto.name:
-            method = "loader_set_dispatch"
-
-        if proto.name == "GetSwapchainInfoKHR":
-            ptype = proto.params[-3].name
-            psize = proto.params[-2].name
-            pdata = proto.params[-1].name
-            cond = ("%s == VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_KHR && "
-                    "%s && %s" % (ptype, pdata, cond))
-            setup.append("VkSwapchainImageInfoKHR *info = %s;" % pdata)
-            setup.append("size_t count = *%s / sizeof(*info), i;" % psize)
-            setup.append("for (i = 0; i < count; i++) {")
-            setup.append("    %s(info[i].image, disp);" % method)
-            setup.append("    %s(info[i].memory, disp);" % method)
-            setup.append("}")
-        else:
-            obj_params = proto.object_out_params()
-            for param in obj_params:
-                setup.append("%s(*%s, disp);" % (method, param.name))
-
-        if setup:
-            joined = "\n        ".join(setup)
-            setup = []
-            setup.append("    if (%s) {" % cond)
-            setup.append("        " + joined)
-            setup.append("    }")
-
-        return "\n".join(setup)
-
-    def _generate_loader_dispatch_entrypoints(self, qual=""):
-        if qual:
-            qual += " "
-
-        funcs = []
-        for proto in self.protos:
-            if self._is_loader_non_trampoline_entrypoint(proto):
-                continue
-            func = []
-
-            obj_setup = self._generate_object_setup(proto)
-
-            func.append(qual + proto.c_func(prefix="vk", attr="VKAPI"))
-            func.append("{")
-
-            # declare local variables
-            func.append("    const VkLayerDispatchTable *disp;")
-            if proto.ret != 'void' and obj_setup:
-                func.append("    VkResult res;")
-            func.append("")
-
-            # get dispatch table
-            func.append("    disp = loader_get_dispatch(%s);" %
-                    proto.params[0].name)
-            func.append("")
-
-            # dispatch!
-            dispatch = "disp->%s;" % proto.c_call()
-            if proto.ret == 'void':
-                func.append("    " + dispatch)
-            elif not obj_setup:
-                func.append("    return " + dispatch)
-            else:
-                func.append("    res = " + dispatch)
-                func.append(obj_setup)
-                func.append("")
-                func.append("    return res;")
-
-            func.append("}")
-
-            funcs.append("\n".join(func))
-
-        return "\n\n".join(funcs)
-
-    def generate_body(self):
-        body = [self._generate_loader_dispatch_entrypoints("LOADER_EXPORT")]
-
-        return "\n\n".join(body)
-
 class DispatchTableOpsSubcommand(Subcommand):
     def run(self):
         if len(self.argv) != 1:
@@ -372,65 +251,6 @@
 
         return "\n".join(body)
 
-class LoaderGetProcAddrSubcommand(Subcommand):
-    def run(self):
-        self.prefix = "vk"
-
-        # we could get the list from argv if wanted
-        self.intercepted = [proto.name for proto in self.protos]
-
-        for proto in self.protos:
-            if proto.name == "GetDeviceProcAddr":
-                self.gpa = proto
-
-        super().run()
-
-    def generate_header(self):
-        return "\n".join(["#include <string.h>"])
-
-    def generate_body(self):
-        lookups = []
-        for proto in self.protos:
-            if proto.name not in self.intercepted:
-                lookups.append("/* no %s%s */" % (self.prefix, proto.name))
-                continue
-
-            lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
-            lookups.append("    return (%s) %s%s;" %
-                    (self.gpa.ret, self.prefix, proto.name))
-
-        special_lookups = []
-        for proto in self.protos:
-            if self._is_loader_non_trampoline_entrypoint(proto) or self._requires_special_trampoline_code(proto.name):
-                special_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
-                special_lookups.append("    return (%s) %s%s;" %
-                        (self.gpa.ret, self.prefix, proto.name))
-            else:
-                continue
-        body = []
-        body.append("static inline %s globalGetProcAddr(const char *name)" %
-                self.gpa.ret)
-        body.append("{")
-        body.append(generate_get_proc_addr_check("name"))
-        body.append("")
-        body.append("    name += 2;")
-        body.append("    %s" % "\n    ".join(lookups))
-        body.append("")
-        body.append("    return NULL;")
-        body.append("}")
-        body.append("")
-        body.append("static inline void *loader_non_passthrough_gpa(const char *name)")
-        body.append("{")
-        body.append(generate_get_proc_addr_check("name"))
-        body.append("")
-        body.append("    name += 2;")
-        body.append("    %s" % "\n    ".join(special_lookups))
-        body.append("")
-        body.append("    return NULL;")
-        body.append("}")
-
-        return "\n".join(body)
-
 def main():
 
     wsi = {
@@ -443,11 +263,8 @@
     }
 
     subcommands = {
-            "dev-ext-trampoline": DevExtTrampolineSubcommand,
-            "loader-entrypoints": LoaderEntrypointsSubcommand,
             "dispatch-table-ops": DispatchTableOpsSubcommand,
             "win-def-file": WinDefFileSubcommand,
-            "loader-get-proc-addr": LoaderGetProcAddrSubcommand,
     }
 
     if len(sys.argv) < 3 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands:
diff --git a/loader/wsi.c b/loader/wsi.c
index a74cdb4..e4a282f 100644
--- a/loader/wsi.c
+++ b/loader/wsi.c
@@ -30,52 +30,9 @@
 #include "wsi.h"
 #include <vulkan/vk_icd.h>
 
-static const VkExtensionProperties wsi_surface_extension_info = {
-    .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_SURFACE_SPEC_VERSION,
-};
-
-#ifdef VK_USE_PLATFORM_WIN32_KHR
-static const VkExtensionProperties wsi_win32_surface_extension_info = {
-    .extensionName = VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_WIN32_SURFACE_SPEC_VERSION,
-};
-#endif // VK_USE_PLATFORM_WIN32_KHR
-
-#ifdef VK_USE_PLATFORM_MIR_KHR
-static const VkExtensionProperties wsi_mir_surface_extension_info = {
-    .extensionName = VK_KHR_MIR_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_MIR_SURFACE_SPEC_VERSION,
-};
-#endif // VK_USE_PLATFORM_MIR_KHR
-
-#ifdef VK_USE_PLATFORM_WAYLAND_KHR
-static const VkExtensionProperties wsi_wayland_surface_extension_info = {
-    .extensionName = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_WAYLAND_SURFACE_SPEC_VERSION,
-};
-#endif // VK_USE_PLATFORM_WAYLAND_KHR
-
-#ifdef VK_USE_PLATFORM_XCB_KHR
-static const VkExtensionProperties wsi_xcb_surface_extension_info = {
-    .extensionName = VK_KHR_XCB_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_XCB_SURFACE_SPEC_VERSION,
-};
-#endif // VK_USE_PLATFORM_XCB_KHR
-
-#ifdef VK_USE_PLATFORM_XLIB_KHR
-static const VkExtensionProperties wsi_xlib_surface_extension_info = {
-    .extensionName = VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_XLIB_SURFACE_SPEC_VERSION,
-};
-#endif // VK_USE_PLATFORM_XLIB_KHR
-
-#ifdef VK_USE_PLATFORM_ANDROID_KHR
-static const VkExtensionProperties wsi_android_surface_extension_info = {
-    .extensionName = VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
-    .specVersion = VK_KHR_ANDROID_SURFACE_REVISION,
-};
-#endif // VK_USE_PLATFORM_ANDROID_KHR
+// The first ICD/Loader interface that support querying the SurfaceKHR from
+// the ICDs.
+#define ICD_VER_SUPPORTS_ICD_SURFACE_KHR 3
 
 void wsi_create_instance(struct loader_instance *ptr_instance,
                          const VkInstanceCreateInfo *pCreateInfo) {
@@ -207,7 +164,33 @@
                              const VkAllocationCallbacks *pAllocator) {
     struct loader_instance *ptr_instance = loader_get_instance(instance);
 
-    loader_instance_heap_free(ptr_instance, (void *)surface);
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+    if (NULL != icd_surface) {
+        if (NULL != icd_surface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                if (ptr_instance->icd_libs.list[i].interface_version >=
+                    ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+                    struct loader_icd *icd = &ptr_instance->icds[i];
+                    if (NULL != icd->DestroySurfaceKHR &&
+                        NULL != (void *)icd_surface->real_icd_surfaces[i]) {
+                        icd->DestroySurfaceKHR(
+                            icd->instance, icd_surface->real_icd_surfaces[i],
+                            pAllocator);
+                        icd_surface->real_icd_surfaces[i] = (VkSurfaceKHR)NULL;
+                    }
+                } else {
+                    // The real_icd_surface for any ICD not supporting the
+                    // proper interface version should be NULL.  If not, then
+                    // we have a problem.
+                    assert(NULL == (void *)icd_surface->real_icd_surfaces[i]);
+                }
+            }
+            loader_instance_heap_free(ptr_instance,
+                                      icd_surface->real_icd_surfaces);
+        }
+
+        loader_instance_heap_free(ptr_instance, (void *)surface);
+    }
 }
 
 // This is the trampoline entrypoint for GetPhysicalDeviceSurfaceSupportKHR
@@ -252,6 +235,14 @@
     assert(icd->GetPhysicalDeviceSurfaceSupportKHR &&
            "loader: null GetPhysicalDeviceSurfaceSupportKHR ICD pointer");
 
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+    if (NULL != icd_surface->real_icd_surfaces &&
+        NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+        return icd->GetPhysicalDeviceSurfaceSupportKHR(
+            phys_dev->phys_dev, queueFamilyIndex,
+            icd_surface->real_icd_surfaces[phys_dev->icd_index], pSupported);
+    }
+
     return icd->GetPhysicalDeviceSurfaceSupportKHR(
         phys_dev->phys_dev, queueFamilyIndex, surface, pSupported);
 }
@@ -298,6 +289,15 @@
     assert(icd->GetPhysicalDeviceSurfaceCapabilitiesKHR &&
            "loader: null GetPhysicalDeviceSurfaceCapabilitiesKHR ICD pointer");
 
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+    if (NULL != icd_surface->real_icd_surfaces &&
+        NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+        return icd->GetPhysicalDeviceSurfaceCapabilitiesKHR(
+            phys_dev->phys_dev,
+            icd_surface->real_icd_surfaces[phys_dev->icd_index],
+            pSurfaceCapabilities);
+    }
+
     return icd->GetPhysicalDeviceSurfaceCapabilitiesKHR(
         phys_dev->phys_dev, surface, pSurfaceCapabilities);
 }
@@ -345,6 +345,15 @@
     assert(icd->GetPhysicalDeviceSurfaceFormatsKHR &&
            "loader: null GetPhysicalDeviceSurfaceFormatsKHR ICD pointer");
 
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+    if (NULL != icd_surface->real_icd_surfaces &&
+        NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+        return icd->GetPhysicalDeviceSurfaceFormatsKHR(
+            phys_dev->phys_dev,
+            icd_surface->real_icd_surfaces[phys_dev->icd_index],
+            pSurfaceFormatCount, pSurfaceFormats);
+    }
+
     return icd->GetPhysicalDeviceSurfaceFormatsKHR(
         phys_dev->phys_dev, surface, pSurfaceFormatCount, pSurfaceFormats);
 }
@@ -391,6 +400,15 @@
     assert(icd->GetPhysicalDeviceSurfacePresentModesKHR &&
            "loader: null GetPhysicalDeviceSurfacePresentModesKHR ICD pointer");
 
+    VkIcdSurface *icd_surface = (VkIcdSurface *)(surface);
+    if (NULL != icd_surface->real_icd_surfaces &&
+        NULL != (void *)icd_surface->real_icd_surfaces[phys_dev->icd_index]) {
+        return icd->GetPhysicalDeviceSurfacePresentModesKHR(
+            phys_dev->phys_dev,
+            icd_surface->real_icd_surfaces[phys_dev->icd_index],
+            pPresentModeCount, pPresentModes);
+    }
+
     return icd->GetPhysicalDeviceSurfacePresentModesKHR(
         phys_dev->phys_dev, surface, pPresentModeCount, pPresentModes);
 }
@@ -407,6 +425,36 @@
                                     pSwapchain);
 }
 
+VKAPI_ATTR VkResult VKAPI_CALL terminator_vkCreateSwapchainKHR(
+    VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain) {
+    uint32_t icd_index = 0;
+    struct loader_device *dev;
+    struct loader_icd *icd = loader_get_icd_and_device(device, &dev, &icd_index);
+    if (NULL != icd &&
+        NULL != icd->CreateSwapchainKHR) {
+        VkIcdSurface *icd_surface = (VkIcdSurface *)(pCreateInfo->surface);
+        if (NULL != icd_surface->real_icd_surfaces) {
+            if (NULL != (void *)icd_surface->real_icd_surfaces[icd_index]) {
+                // We found the ICD, and there is an ICD KHR surface
+                // associated with it, so copy the CreateInfo struct
+                // and point it at the ICD's surface.
+                VkSwapchainCreateInfoKHR *pCreateCopy =
+                    loader_stack_alloc(sizeof(VkSwapchainCreateInfoKHR));
+                if (NULL == pCreateCopy) {
+                    return VK_ERROR_OUT_OF_HOST_MEMORY;
+                }
+                memcpy(pCreateCopy, pCreateInfo, sizeof(VkSwapchainCreateInfoKHR));
+                pCreateCopy->surface =
+                    icd_surface->real_icd_surfaces[icd_index];
+                return icd->CreateSwapchainKHR(device, pCreateCopy, pAllocator, pSwapchain);
+            }
+        }
+        return icd->CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
+    }
+    return VK_SUCCESS;
+}
+
 // This is the trampoline entrypoint for DestroySwapchainKHR
 LOADER_EXPORT VKAPI_ATTR void VKAPI_CALL
 vkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain,
@@ -416,22 +464,26 @@
     disp->DestroySwapchainKHR(device, swapchain, pAllocator);
 }
 
-// This is the trampoline entrypoint for GetSwapchainImagesKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain,
-                        uint32_t *pSwapchainImageCount,
-                        VkImage *pSwapchainImages) {
+/*
+ * This is the trampoline entrypoint
+ * for GetSwapchainImagesKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainImagesKHR(
+    VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,
+    VkImage *pSwapchainImages) {
     const VkLayerDispatchTable *disp;
     disp = loader_get_dispatch(device);
     return disp->GetSwapchainImagesKHR(
         device, swapchain, pSwapchainImageCount, pSwapchainImages);
 }
 
-// This is the trampoline entrypoint for AcquireNextImageKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain,
-                      uint64_t timeout, VkSemaphore semaphore, VkFence fence,
-                      uint32_t *pImageIndex) {
+/*
+ * This is the trampoline entrypoint
+ * for AcquireNextImageKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(
+    VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout,
+    VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex) {
     const VkLayerDispatchTable *disp;
     disp = loader_get_dispatch(device);
     return disp->AcquireNextImageKHR(device, swapchain, timeout,
@@ -446,6 +498,40 @@
     return disp->QueuePresentKHR(queue, pPresentInfo);
 }
 
+static VkIcdSurface *AllocateIcdSurfaceStruct(struct loader_instance *instance,
+                                              size_t base_size,
+                                              size_t platform_size,
+                                              bool create_icd_surfs) {
+    // Next, if so, proceed with the implementation of this function:
+    VkIcdSurface *pIcdSurface = loader_instance_heap_alloc(
+        instance, sizeof(VkIcdSurface), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+    if (pIcdSurface != NULL) {
+        // Setup the new sizes and offsets so we can grow the structures in the
+        // future without having problems
+        pIcdSurface->base_size = (uint32_t)base_size;
+        pIcdSurface->platform_size = (uint32_t)platform_size;
+        pIcdSurface->non_platform_offset = (uint32_t)(
+            (uint8_t *)(&pIcdSurface->base_size) - (uint8_t *)pIcdSurface);
+        pIcdSurface->entire_size = sizeof(VkIcdSurface);
+
+        if (create_icd_surfs) {
+            pIcdSurface->real_icd_surfaces = loader_instance_heap_alloc(
+                instance, sizeof(VkSurfaceKHR) * instance->total_icd_count,
+                VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+            if (pIcdSurface->real_icd_surfaces == NULL) {
+                loader_instance_heap_free(instance, pIcdSurface);
+                pIcdSurface = NULL;
+            } else {
+                memset(pIcdSurface->real_icd_surfaces, 0,
+                       sizeof(VkSurfaceKHR) * instance->total_icd_count);
+            }
+        } else {
+            pIcdSurface->real_icd_surfaces = NULL;
+        }
+    }
+    return pIcdSurface;
+}
+
 #ifdef VK_USE_PLATFORM_WIN32_KHR
 
 
@@ -468,32 +554,69 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWin32SurfaceKHR(
     VkInstance instance, const VkWin32SurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
+    // Initialize pSurface to NULL just to be safe.
+    *pSurface = VK_NULL_HANDLE;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_win32_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_win32_surface extension not enabled.  "
                    "vkCreateWin32SurfaceKHR not executed!\n");
-        return VK_ERROR_EXTENSION_NOT_PRESENT;
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceWin32 *pIcdSurface = NULL;
-
-    pIcdSurface =
-        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWin32),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->win_surf.base),
+        sizeof(pIcdSurface->win_surf), true);
     if (pIcdSurface == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WIN32;
-    pIcdSurface->hinstance = pCreateInfo->hinstance;
-    pIcdSurface->hwnd = pCreateInfo->hwnd;
+    pIcdSurface->win_surf.base.platform = VK_ICD_WSI_PLATFORM_WIN32;
+    pIcdSurface->win_surf.hinstance = pCreateInfo->hinstance;
+    pIcdSurface->win_surf.hwnd = pCreateInfo->hwnd;
 
-    *pSurface = (VkSurfaceKHR)pIcdSurface;
+    // Loop through each ICD and determine if they need to create a surface
+    for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+        if (ptr_instance->icd_libs.list[i].interface_version >=
+            ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            struct loader_icd *icd = &ptr_instance->icds[i];
+            if (NULL != icd->CreateWin32SurfaceKHR) {
+                vkRes = icd->CreateWin32SurfaceKHR(
+                    icd->instance, pCreateInfo, pAllocator,
+                    &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
 
-    return VK_SUCCESS;
+    *pSurface = (VkSurfaceKHR)(pIcdSurface);
+
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                struct loader_icd *icd = &ptr_instance->icds[i];
+                if (NULL != (void*)pIcdSurface->real_icd_surfaces[i] &&
+                    NULL != icd->DestroySurfaceKHR) {
+                    icd->DestroySurfaceKHR(
+                        icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
 }
 
 // This is the trampoline entrypoint for
@@ -561,32 +684,67 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateMirSurfaceKHR(
     VkInstance instance, const VkMirSurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_mir_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_mir_surface extension not enabled.  "
                    "vkCreateMirSurfaceKHR not executed!\n");
-        return VK_ERROR_EXTENSION_NOT_PRESENT;
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceMir *pIcdSurface = NULL;
-
-    pIcdSurface =
-        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceMir),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->mir_surf.base),
+        sizeof(pIcdSurface->mir_surf), true);
     if (pIcdSurface == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_MIR;
-    pIcdSurface->connection = pCreateInfo->connection;
-    pIcdSurface->mirSurface = pCreateInfo->mirSurface;
+    pIcdSurface->mir_surf.base.platform = VK_ICD_WSI_PLATFORM_MIR;
+    pIcdSurface->mir_surf.connection = pCreateInfo->connection;
+    pIcdSurface->mir_surf.mirSurface = pCreateInfo->mirSurface;
+
+    // Loop through each ICD and determine if they need to create a surface
+    for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+        if (ptr_instance->icd_libs.list[i].interface_version >=
+            ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            struct loader_icd *icd = &ptr_instance->icds[i];
+            if (NULL != icd->CreateMirSurfaceKHR) {
+                vkRes = icd->CreateMirSurfaceKHR(
+                    icd->instance, pCreateInfo, pAllocator,
+                    &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
 
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
-    return VK_SUCCESS;
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                struct loader_icd *icd = &ptr_instance->icds[i];
+                if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+                    NULL != icd->DestroySurfaceKHR) {
+                    icd->DestroySurfaceKHR(
+                        icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
 }
 
 // This is the trampoline entrypoint for
@@ -637,15 +795,13 @@
 
 #ifdef VK_USE_PLATFORM_WAYLAND_KHR
 
-
-// Functions for the VK_KHR_wayland_surface extension:
-
-// This is the trampoline entrypoint for CreateWaylandSurfaceKHR
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkCreateWaylandSurfaceKHR(VkInstance instance,
-                          const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
-                          const VkAllocationCallbacks *pAllocator,
-                          VkSurfaceKHR *pSurface) {
+/*
+ * This is the trampoline entrypoint
+ * for CreateWaylandSurfaceKHR
+ */
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkCreateWaylandSurfaceKHR(
+    VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     const VkLayerInstanceDispatchTable *disp;
     disp = loader_get_instance_dispatch(instance);
     VkResult res;
@@ -659,32 +815,67 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateWaylandSurfaceKHR(
     VkInstance instance, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_wayland_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_wayland_surface extension not enabled.  "
                    "vkCreateWaylandSurfaceKHR not executed!\n");
-        return VK_ERROR_EXTENSION_NOT_PRESENT;
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceWayland *pIcdSurface = NULL;
-
-    pIcdSurface =
-        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceWayland),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->wayland_surf.base),
+        sizeof(pIcdSurface->wayland_surf), true);
     if (pIcdSurface == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
-    pIcdSurface->display = pCreateInfo->display;
-    pIcdSurface->surface = pCreateInfo->surface;
+    pIcdSurface->wayland_surf.base.platform = VK_ICD_WSI_PLATFORM_WAYLAND;
+    pIcdSurface->wayland_surf.display = pCreateInfo->display;
+    pIcdSurface->wayland_surf.surface = pCreateInfo->surface;
+
+    // Loop through each ICD and determine if they need to create a surface
+    for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+        if (ptr_instance->icd_libs.list[i].interface_version >=
+            ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            struct loader_icd *icd = &ptr_instance->icds[i];
+            if (NULL != icd->CreateWaylandSurfaceKHR) {
+                vkRes = icd->CreateWaylandSurfaceKHR(
+                    icd->instance, pCreateInfo, pAllocator,
+                    &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
 
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
-    return VK_SUCCESS;
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                struct loader_icd *icd = &ptr_instance->icds[i];
+                if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+                    NULL != icd->DestroySurfaceKHR) {
+                    icd->DestroySurfaceKHR(
+                        icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
 }
 
 
@@ -756,32 +947,67 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXcbSurfaceKHR(
     VkInstance instance, const VkXcbSurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_xcb_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_xcb_surface extension not enabled.  "
                    "vkCreateXcbSurfaceKHR not executed!\n");
-        return VK_ERROR_EXTENSION_NOT_PRESENT;
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceXcb *pIcdSurface = NULL;
-
-    pIcdSurface =
-        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXcb),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->xcb_surf.base),
+        sizeof(pIcdSurface->xcb_surf), true);
     if (pIcdSurface == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XCB;
-    pIcdSurface->connection = pCreateInfo->connection;
-    pIcdSurface->window = pCreateInfo->window;
+    pIcdSurface->xcb_surf.base.platform = VK_ICD_WSI_PLATFORM_XCB;
+    pIcdSurface->xcb_surf.connection = pCreateInfo->connection;
+    pIcdSurface->xcb_surf.window = pCreateInfo->window;
+
+    // Loop through each ICD and determine if they need to create a surface
+    for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+        if (ptr_instance->icd_libs.list[i].interface_version >=
+            ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            struct loader_icd *icd = &ptr_instance->icds[i];
+            if (NULL != icd->CreateXcbSurfaceKHR) {
+                vkRes = icd->CreateXcbSurfaceKHR(
+                    icd->instance, pCreateInfo, pAllocator,
+                    &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
 
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
-    return VK_SUCCESS;
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                struct loader_icd *icd = &ptr_instance->icds[i];
+                if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+                    NULL != icd->DestroySurfaceKHR) {
+                    icd->DestroySurfaceKHR(
+                        icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
 }
 
 // This is the trampoline entrypoint for
@@ -852,32 +1078,67 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateXlibSurfaceKHR(
     VkInstance instance, const VkXlibSurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
+    VkResult vkRes = VK_SUCCESS;
+    VkIcdSurface *pIcdSurface = NULL;
     // First, check to ensure the appropriate extension was enabled:
     struct loader_instance *ptr_instance = loader_get_instance(instance);
     if (!ptr_instance->wsi_xlib_surface_enabled) {
         loader_log(ptr_instance, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
                    "VK_KHR_xlib_surface extension not enabled.  "
                    "vkCreateXlibSurfaceKHR not executed!\n");
-        return VK_ERROR_EXTENSION_NOT_PRESENT;
+        vkRes = VK_ERROR_EXTENSION_NOT_PRESENT;
+        goto out;
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceXlib *pIcdSurface = NULL;
-
-    pIcdSurface =
-        loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceXlib),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    pIcdSurface = AllocateIcdSurfaceStruct(
+        ptr_instance, sizeof(pIcdSurface->xlib_surf.base),
+        sizeof(pIcdSurface->xlib_surf), true);
     if (pIcdSurface == NULL) {
-        return VK_ERROR_OUT_OF_HOST_MEMORY;
+        vkRes = VK_ERROR_OUT_OF_HOST_MEMORY;
+        goto out;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_XLIB;
-    pIcdSurface->dpy = pCreateInfo->dpy;
-    pIcdSurface->window = pCreateInfo->window;
+    pIcdSurface->xlib_surf.base.platform = VK_ICD_WSI_PLATFORM_XLIB;
+    pIcdSurface->xlib_surf.dpy = pCreateInfo->dpy;
+    pIcdSurface->xlib_surf.window = pCreateInfo->window;
+
+    // Loop through each ICD and determine if they need to create a surface
+    for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+        if (ptr_instance->icd_libs.list[i].interface_version >=
+            ICD_VER_SUPPORTS_ICD_SURFACE_KHR) {
+            struct loader_icd *icd = &ptr_instance->icds[i];
+            if (NULL != icd->CreateXlibSurfaceKHR) {
+                vkRes = icd->CreateXlibSurfaceKHR(
+                    icd->instance, pCreateInfo, pAllocator,
+                    &pIcdSurface->real_icd_surfaces[i]);
+                if (VK_SUCCESS != vkRes) {
+                    goto out;
+                }
+            }
+        }
+    }
 
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
-    return VK_SUCCESS;
+out:
+
+    if (VK_SUCCESS != vkRes && NULL != pIcdSurface) {
+        if (NULL != pIcdSurface->real_icd_surfaces) {
+            for (uint32_t i = 0; i < ptr_instance->total_icd_count; i++) {
+                struct loader_icd *icd = &ptr_instance->icds[i];
+                if (NULL != pIcdSurface->real_icd_surfaces[i] &&
+                    NULL != icd->DestroySurfaceKHR) {
+                    icd->DestroySurfaceKHR(
+                        icd->instance, pIcdSurface->real_icd_surfaces[i], pAllocator);
+                }
+            }
+            loader_instance_heap_free(ptr_instance, pIcdSurface->real_icd_surfaces);
+        }
+        loader_instance_heap_free(ptr_instance, pIcdSurface);
+    }
+
+    return vkRes;
 }
 
 // This is the trampoline entrypoint for GetPhysicalDeviceXlibPresentationSupportKHR
@@ -956,11 +1217,9 @@
     }
 
     // Next, if so, proceed with the implementation of this function:
-    VkIcdSurfaceAndroid *pIcdSurface = NULL;
-
-    pIcdSurface =
+    VkIcdSurfaceAndroid *pIcdSurface =
         loader_instance_heap_alloc(ptr_instance, sizeof(VkIcdSurfaceAndroid),
-                                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+                                   VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
@@ -1071,11 +1330,9 @@
     return res;
 }
 
-VKAPI_ATTR VkResult VKAPI_CALL
-terminator_GetDisplayPlaneSupportedDisplaysKHR(VkPhysicalDevice physicalDevice,
-                                               uint32_t planeIndex,
-                                               uint32_t *pDisplayCount,
-                                               VkDisplayKHR *pDisplays) {
+VKAPI_ATTR VkResult VKAPI_CALL terminator_GetDisplayPlaneSupportedDisplaysKHR(
+    VkPhysicalDevice physicalDevice, uint32_t planeIndex,
+    uint32_t *pDisplayCount, VkDisplayKHR *pDisplays) {
     // First, check to ensure the appropriate extension was enabled:
     struct loader_physical_device *phys_dev =
         (struct loader_physical_device *)physicalDevice;
@@ -1098,10 +1355,9 @@
         phys_dev->phys_dev, planeIndex, pDisplayCount, pDisplays);
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetDisplayModePropertiesKHR(VkPhysicalDevice physicalDevice,
-                              VkDisplayKHR display, uint32_t *pPropertyCount,
-                              VkDisplayModePropertiesKHR *pProperties) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayModePropertiesKHR(
+    VkPhysicalDevice physicalDevice, VkDisplayKHR display,
+    uint32_t *pPropertyCount, VkDisplayModePropertiesKHR *pProperties) {
     VkPhysicalDevice unwrapped_phys_dev =
         loader_unwrap_physical_device(physicalDevice);
     const VkLayerInstanceDispatchTable *disp;
@@ -1175,10 +1431,9 @@
                                      pAllocator, pMode);
 }
 
-LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
-vkGetDisplayPlaneCapabilitiesKHR(VkPhysicalDevice physicalDevice,
-                                 VkDisplayModeKHR mode, uint32_t planeIndex,
-                                 VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
+LOADER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkGetDisplayPlaneCapabilitiesKHR(
+    VkPhysicalDevice physicalDevice, VkDisplayModeKHR mode, uint32_t planeIndex,
+    VkDisplayPlaneCapabilitiesKHR *pCapabilities) {
     VkPhysicalDevice unwrapped_phys_dev =
         loader_unwrap_physical_device(physicalDevice);
     const VkLayerInstanceDispatchTable *disp;
@@ -1229,7 +1484,7 @@
     VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface) {
     struct loader_instance *inst = loader_get_instance(instance);
-    VkIcdSurfaceDisplay *pIcdSurface = NULL;
+    VkIcdSurface *pIcdSurface = NULL;
 
     if (!inst->wsi_surface_enabled) {
         loader_log(inst, VK_DEBUG_REPORT_ERROR_BIT_EXT, 0,
@@ -1238,20 +1493,23 @@
         return VK_ERROR_EXTENSION_NOT_PRESENT;
     }
 
-    pIcdSurface = loader_instance_heap_alloc(
-        inst, sizeof(VkIcdSurfaceDisplay), VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+    // The VK_KHR_display path will continue to use the old path (hence the
+    // false as the last parameter).
+    pIcdSurface =
+        AllocateIcdSurfaceStruct(inst, sizeof(pIcdSurface->display_surf.base),
+                                 sizeof(pIcdSurface->display_surf), false);
     if (pIcdSurface == NULL) {
         return VK_ERROR_OUT_OF_HOST_MEMORY;
     }
 
-    pIcdSurface->base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
-    pIcdSurface->displayMode = pCreateInfo->displayMode;
-    pIcdSurface->planeIndex = pCreateInfo->planeIndex;
-    pIcdSurface->planeStackIndex = pCreateInfo->planeStackIndex;
-    pIcdSurface->transform = pCreateInfo->transform;
-    pIcdSurface->globalAlpha = pCreateInfo->globalAlpha;
-    pIcdSurface->alphaMode = pCreateInfo->alphaMode;
-    pIcdSurface->imageExtent = pCreateInfo->imageExtent;
+    pIcdSurface->display_surf.base.platform = VK_ICD_WSI_PLATFORM_DISPLAY;
+    pIcdSurface->display_surf.displayMode = pCreateInfo->displayMode;
+    pIcdSurface->display_surf.planeIndex = pCreateInfo->planeIndex;
+    pIcdSurface->display_surf.planeStackIndex = pCreateInfo->planeStackIndex;
+    pIcdSurface->display_surf.transform = pCreateInfo->transform;
+    pIcdSurface->display_surf.globalAlpha = pCreateInfo->globalAlpha;
+    pIcdSurface->display_surf.alphaMode = pCreateInfo->alphaMode;
+    pIcdSurface->display_surf.imageExtent = pCreateInfo->imageExtent;
 
     *pSurface = (VkSurfaceKHR)pIcdSurface;
 
diff --git a/loader/wsi.h b/loader/wsi.h
index fa60088..77cc183 100644
--- a/loader/wsi.h
+++ b/loader/wsi.h
@@ -19,9 +19,38 @@
  *
  */
 
+#ifndef WSI_H
+#define WSI_H
+
 #include "vk_loader_platform.h"
 #include "loader.h"
 
+typedef struct {
+    union {
+#ifdef VK_USE_PLATFORM_MIR_KHR
+        VkIcdSurfaceMir mir_surf;
+#endif // VK_USE_PLATFORM_MIR_KHR
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+        VkIcdSurfaceWayland wayland_surf;
+#endif // VK_USE_PLATFORM_WAYLAND_KHR
+#ifdef VK_USE_PLATFORM_WIN32_KHR
+        VkIcdSurfaceWin32 win_surf;
+#endif // VK_USE_PLATFORM_WIN32_KHR
+#ifdef VK_USE_PLATFORM_XCB_KHR
+        VkIcdSurfaceXcb xcb_surf;
+#endif // VK_USE_PLATFORM_XCB_KHR
+#ifdef VK_USE_PLATFORM_XLIB_KHR
+        VkIcdSurfaceXlib xlib_surf;
+#endif // VK_USE_PLATFORM_XLIB_KHR
+        VkIcdSurfaceDisplay display_surf;
+    };
+    uint32_t base_size; // Size of VkIcdSurfaceBase
+    uint32_t platform_size; // Size of corresponding VkIcdSurfaceXXX
+    uint32_t non_platform_offset; // Start offset to base_size
+    uint32_t entire_size; // Size of entire VkIcdSurface
+    VkSurfaceKHR *real_icd_surfaces;
+} VkIcdSurface;
+
 bool wsi_swapchain_instance_gpa(struct loader_instance *ptr_instance,
                                 const char *name, void **addr);
 
@@ -29,6 +58,10 @@
                          const VkInstanceCreateInfo *pCreateInfo);
 bool wsi_unsupported_instance_extension(const VkExtensionProperties *ext_prop);
 
+VKAPI_ATTR VkResult VKAPI_CALL terminator_vkCreateSwapchainKHR(
+    VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo,
+    const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain);
+
 VKAPI_ATTR void VKAPI_CALL
 terminator_DestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
                              const VkAllocationCallbacks *pAllocator);
@@ -135,3 +168,5 @@
 VKAPI_ATTR VkResult VKAPI_CALL terminator_CreateDisplayPlaneSurfaceKHR(
     VkInstance instance, const VkDisplaySurfaceCreateInfoKHR *pCreateInfo,
     const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface);
+
+#endif /* WSI_H */
diff --git a/lvl_genvk.py b/lvl_genvk.py
new file mode 100644
index 0000000..8fa7c1b
--- /dev/null
+++ b/lvl_genvk.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2013-2016 The Khronos Group 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.
+
+import argparse, cProfile, pdb, string, sys, time
+from reg import *
+from generator import write
+
+#
+# LoaderAndValidationLayer Generator Additions
+from threading_generator import  ThreadGeneratorOptions, ThreadOutputGenerator
+from parameter_validation_generator import ParamCheckerGeneratorOptions, ParamCheckerOutputGenerator
+from unique_objects_generator import UniqueObjectsGeneratorOptions, UniqueObjectsOutputGenerator
+
+# Simple timer functions
+startTime = None
+
+def startTimer(timeit):
+    global startTime
+    startTime = time.clock()
+
+def endTimer(timeit, msg):
+    global startTime
+    endTime = time.clock()
+    if (timeit):
+        write(msg, endTime - startTime, file=sys.stderr)
+        startTime = None
+
+# Turn a list of strings into a regexp string matching exactly those strings
+def makeREstring(list):
+    return '^(' + '|'.join(list) + ')$'
+
+# Returns a directory of [ generator function, generator options ] indexed
+# by specified short names. The generator options incorporate the following
+# parameters:
+#
+# extensions - list of extension names to include.
+# protect - True if re-inclusion protection should be added to headers
+# directory - path to directory in which to generate the target(s)
+def makeGenOpts(extensions = [], protect = True, directory = '.'):
+    global genOpts
+    genOpts = {}
+
+    # Descriptive names for various regexp patterns used to select
+    # versions and extensions
+    allVersions     = allExtensions = '.*'
+    noVersions      = noExtensions = None
+
+    addExtensions     = makeREstring(extensions)
+    removeExtensions  = makeREstring([])
+
+    # Copyright text prefixing all headers (list of strings).
+    prefixStrings = [
+        '/*',
+        '** Copyright (c) 2015-2016 The Khronos Group 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.',
+        '*/',
+        ''
+    ]
+
+    # Text specific to Vulkan headers
+    vkPrefixStrings = [
+        '/*',
+        '** This header is generated from the Khronos Vulkan XML API Registry.',
+        '**',
+        '*/',
+        ''
+    ]
+
+    # Defaults for generating re-inclusion protection wrappers (or not)
+    protectFile = protect
+    protectFeature = protect
+    protectProto = protect
+
+    #
+    # LoaderAndValidationLayer Generators
+    # Options for threading layer
+    genOpts['thread_check.h'] = [
+          ThreadOutputGenerator,
+          ThreadGeneratorOptions(
+            filename          = 'thread_check.h',
+            directory         = directory,
+            apiname           = 'vulkan',
+            profile           = None,
+            versions          = allVersions,
+            emitversions      = allVersions,
+            defaultExtensions = 'vulkan',
+            addExtensions     = addExtensions,
+            removeExtensions  = removeExtensions,
+            prefixText        = prefixStrings + vkPrefixStrings,
+            protectFeature    = False,
+            apicall           = 'VKAPI_ATTR ',
+            apientry          = 'VKAPI_CALL ',
+            apientryp         = 'VKAPI_PTR *',
+            alignFuncParam    = 48)
+        ]
+
+    # Options for parameter validation layer
+    genOpts['parameter_validation.h'] = [
+          ParamCheckerOutputGenerator,
+          ParamCheckerGeneratorOptions(
+            filename          = 'parameter_validation.h',
+            directory         = directory,
+            apiname           = 'vulkan',
+            profile           = None,
+            versions          = allVersions,
+            emitversions      = allVersions,
+            defaultExtensions = 'vulkan',
+            addExtensions     = addExtensions,
+            removeExtensions  = removeExtensions,
+            prefixText        = prefixStrings + vkPrefixStrings,
+            protectFeature    = False,
+            apicall           = 'VKAPI_ATTR ',
+            apientry          = 'VKAPI_CALL ',
+            apientryp         = 'VKAPI_PTR *',
+            alignFuncParam    = 48)
+        ]
+
+    # Options for unique objects layer
+    genOpts['unique_objects_wrappers.h'] = [
+          UniqueObjectsOutputGenerator,
+          UniqueObjectsGeneratorOptions(
+            filename          = 'unique_objects_wrappers.h',
+            directory         = directory,
+            apiname           = 'vulkan',
+            profile           = None,
+            versions          = allVersions,
+            emitversions      = allVersions,
+            defaultExtensions = 'vulkan',
+            addExtensions     = addExtensions,
+            removeExtensions  = removeExtensions,
+            prefixText        = prefixStrings + vkPrefixStrings,
+            protectFeature    = False,
+            apicall           = 'VKAPI_ATTR ',
+            apientry          = 'VKAPI_CALL ',
+            apientryp         = 'VKAPI_PTR *',
+            alignFuncParam    = 48)
+        ]
+
+# Generate a target based on the options in the matching genOpts{} object.
+# This is encapsulated in a function so it can be profiled and/or timed.
+# The args parameter is an parsed argument object containing the following
+# fields that are used:
+#   target - target to generate
+#   directory - directory to generate it in
+#   protect - True if re-inclusion wrappers should be created
+#   extensions - list of additional extensions to include in generated
+#   interfaces
+def genTarget(args):
+    global genOpts
+
+    # Create generator options with specified parameters
+    makeGenOpts(extensions = args.extension,
+                protect = args.protect,
+                directory = args.directory)
+
+    if (args.target in genOpts.keys()):
+        createGenerator = genOpts[args.target][0]
+        options = genOpts[args.target][1]
+
+        write('* Building', options.filename, file=sys.stderr)
+
+        startTimer(args.time)
+        gen = createGenerator(errFile=errWarn,
+                              warnFile=errWarn,
+                              diagFile=diag)
+        reg.setGenerator(gen)
+        reg.apiGen(options)
+        write('* Generated', options.filename, file=sys.stderr)
+        endTimer(args.time, '* Time to generate ' + options.filename + ' =')
+    else:
+        write('No generator options for unknown target:',
+              args.target, file=sys.stderr)
+
+# -extension name - may be a single extension name, a a space-separated list
+# of names, or a regular expression.
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument('-extension', action='append',
+                        default=[],
+                        help='Specify an extension or extensions to add to targets')
+    parser.add_argument('-debug', action='store_true',
+                        help='Enable debugging')
+    parser.add_argument('-dump', action='store_true',
+                        help='Enable dump to stderr')
+    parser.add_argument('-diagfile', action='store',
+                        default=None,
+                        help='Write diagnostics to specified file')
+    parser.add_argument('-errfile', action='store',
+                        default=None,
+                        help='Write errors and warnings to specified file instead of stderr')
+    parser.add_argument('-noprotect', dest='protect', action='store_false',
+                        help='Disable inclusion protection in output headers')
+    parser.add_argument('-profile', action='store_true',
+                        help='Enable profiling')
+    parser.add_argument('-registry', action='store',
+                        default='vk.xml',
+                        help='Use specified registry file instead of vk.xml')
+    parser.add_argument('-time', action='store_true',
+                        help='Enable timing')
+    parser.add_argument('-validate', action='store_true',
+                        help='Enable group validation')
+    parser.add_argument('-o', action='store', dest='directory',
+                        default='.',
+                        help='Create target and related files in specified directory')
+    parser.add_argument('target', metavar='target', nargs='?',
+                        help='Specify target')
+
+    args = parser.parse_args()
+
+    # This splits arguments which are space-separated lists
+    args.extension = [name for arg in args.extension for name in arg.split()]
+
+    # Load & parse registry
+    reg = Registry()
+
+    startTimer(args.time)
+    tree = etree.parse(args.registry)
+    endTimer(args.time, '* Time to make ElementTree =')
+
+    startTimer(args.time)
+    reg.loadElementTree(tree)
+    endTimer(args.time, '* Time to parse ElementTree =')
+
+    if (args.validate):
+        reg.validateGroups()
+
+    if (args.dump):
+        write('* Dumping registry to regdump.txt', file=sys.stderr)
+        reg.dumpReg(filehandle = open('regdump.txt','w'))
+
+    # create error/warning & diagnostic files
+    if (args.errfile):
+        errWarn = open(args.errfile, 'w')
+    else:
+        errWarn = sys.stderr
+
+    if (args.diagfile):
+        diag = open(args.diagfile, 'w')
+    else:
+        diag = None
+
+    if (args.debug):
+        pdb.run('genTarget(args)')
+    elif (args.profile):
+        import cProfile, pstats
+        cProfile.run('genTarget(args)', 'profile.txt')
+        p = pstats.Stats('profile.txt')
+        p.strip_dirs().sort_stats('time').print_stats(50)
+    else:
+        genTarget(args)
diff --git a/parameter_validation_generator.py b/parameter_validation_generator.py
new file mode 100644
index 0000000..e0d215d
--- /dev/null
+++ b/parameter_validation_generator.py
@@ -0,0 +1,987 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2016 The Khronos Group Inc.
+# Copyright (c) 2015-2016 Valve Corporation
+# Copyright (c) 2015-2016 LunarG, Inc.
+# Copyright (c) 2015-2016 Google 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: Dustin Graves <dustin@lunarg.com>
+
+import os,re,sys
+import xml.etree.ElementTree as etree
+from generator import *
+from collections import namedtuple
+
+
+# ParamCheckerGeneratorOptions - subclass of GeneratorOptions.
+#
+# Adds options used by ParamCheckerOutputGenerator object during Parameter
+# validation layer generation.
+#
+# Additional members
+#   prefixText - list of strings to prefix generated header with
+#     (usually a copyright statement + calling convention macros).
+#   protectFile - True if multiple inclusion protection should be
+#     generated (based on the filename) around the entire header.
+#   protectFeature - True if #ifndef..#endif protection should be
+#     generated around a feature interface in the header file.
+#   genFuncPointers - True if function pointer typedefs should be
+#     generated
+#   protectProto - If conditional protection should be generated
+#     around prototype declarations, set to either '#ifdef'
+#     to require opt-in (#ifdef protectProtoStr) or '#ifndef'
+#     to require opt-out (#ifndef protectProtoStr). Otherwise
+#     set to None.
+#   protectProtoStr - #ifdef/#ifndef symbol to use around prototype
+#     declarations, if protectProto is set
+#   apicall - string to use for the function declaration prefix,
+#     such as APICALL on Windows.
+#   apientry - string to use for the calling convention macro,
+#     in typedefs, such as APIENTRY.
+#   apientryp - string to use for the calling convention macro
+#     in function pointer typedefs, such as APIENTRYP.
+#   indentFuncProto - True if prototype declarations should put each
+#     parameter on a separate line
+#   indentFuncPointer - True if typedefed function pointers should put each
+#     parameter on a separate line
+#   alignFuncParam - if nonzero and parameters are being put on a
+#     separate line, align parameter names at the specified column
+class ParamCheckerGeneratorOptions(GeneratorOptions):
+    def __init__(self,
+                 filename = None,
+                 directory = '.',
+                 apiname = None,
+                 profile = None,
+                 versions = '.*',
+                 emitversions = '.*',
+                 defaultExtensions = None,
+                 addExtensions = None,
+                 removeExtensions = None,
+                 sortProcedure = regSortFeatures,
+                 prefixText = "",
+                 genFuncPointers = True,
+                 protectFile = True,
+                 protectFeature = True,
+                 protectProto = None,
+                 protectProtoStr = None,
+                 apicall = '',
+                 apientry = '',
+                 apientryp = '',
+                 indentFuncProto = True,
+                 indentFuncPointer = False,
+                 alignFuncParam = 0):
+        GeneratorOptions.__init__(self, filename, directory, apiname, profile,
+                                  versions, emitversions, defaultExtensions,
+                                  addExtensions, removeExtensions, sortProcedure)
+        self.prefixText      = prefixText
+        self.genFuncPointers = genFuncPointers
+        self.protectFile     = protectFile
+        self.protectFeature  = protectFeature
+        self.protectProto    = protectProto
+        self.protectProtoStr = protectProtoStr
+        self.apicall         = apicall
+        self.apientry        = apientry
+        self.apientryp       = apientryp
+        self.indentFuncProto = indentFuncProto
+        self.indentFuncPointer = indentFuncPointer
+        self.alignFuncParam  = alignFuncParam
+
+# ParamCheckerOutputGenerator - subclass of OutputGenerator.
+# Generates param checker layer code.
+#
+# ---- methods ----
+# ParamCheckerOutputGenerator(errFile, warnFile, diagFile) - args as for
+#   OutputGenerator. Defines additional internal state.
+# ---- methods overriding base class ----
+# beginFile(genOpts)
+# endFile()
+# beginFeature(interface, emit)
+# endFeature()
+# genType(typeinfo,name)
+# genStruct(typeinfo,name)
+# genGroup(groupinfo,name)
+# genEnum(enuminfo, name)
+# genCmd(cmdinfo)
+class ParamCheckerOutputGenerator(OutputGenerator):
+    """Generate ParamChecker code based on XML element attributes"""
+    # This is an ordered list of sections in the header file.
+    ALL_SECTIONS = ['command']
+    def __init__(self,
+                 errFile = sys.stderr,
+                 warnFile = sys.stderr,
+                 diagFile = sys.stdout):
+        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
+        self.INDENT_SPACES = 4
+        # Commands to ignore
+        self.blacklist = [
+            'vkGetInstanceProcAddr',
+            'vkGetDeviceProcAddr',
+            'vkEnumerateInstanceLayerProperties',
+            'vkEnumerateInstanceExtensionsProperties',
+            'vkEnumerateDeviceLayerProperties',
+            'vkEnumerateDeviceExtensionsProperties',
+            'vkCreateDebugReportCallbackEXT',
+            'vkDebugReportMessageEXT']
+        # Validation conditions for some special case struct members that are conditionally validated
+        self.structMemberValidationConditions = { 'VkPipelineColorBlendStateCreateInfo' : { 'logicOp' : '{}logicOpEnable == VK_TRUE' } }
+        # Header version
+        self.headerVersion = None
+        # Internal state - accumulators for different inner block text
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        self.structNames = []                             # List of Vulkan struct typenames
+        self.stypes = []                                  # Values from the VkStructureType enumeration
+        self.structTypes = dict()                         # Map of Vulkan struct typename to required VkStructureType
+        self.handleTypes = set()                          # Set of handle type names
+        self.commands = []                                # List of CommandData records for all Vulkan commands
+        self.structMembers = []                           # List of StructMemberData records for all Vulkan structs
+        self.validatedStructs = dict()                    # Map of structs type names to generated validation code for that struct type
+        self.enumRanges = dict()                          # Map of enum name to BEGIN/END range values
+        self.flags = set()                                # Map of flags typenames
+        self.flagBits = dict()                            # Map of flag bits typename to list of values
+        # Named tuples to store struct and command data
+        self.StructType = namedtuple('StructType', ['name', 'value'])
+        self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isstaticarray', 'isbool', 'israngedenum',
+                                                        'isconst', 'isoptional', 'iscount', 'noautovalidity', 'len', 'extstructs',
+                                                        'condition', 'cdecl'])
+        self.CommandData = namedtuple('CommandData', ['name', 'params', 'cdecl'])
+        self.StructMemberData = namedtuple('StructMemberData', ['name', 'members'])
+    #
+    def incIndent(self, indent):
+        inc = ' ' * self.INDENT_SPACES
+        if indent:
+            return indent + inc
+        return inc
+    #
+    def decIndent(self, indent):
+        if indent and (len(indent) > self.INDENT_SPACES):
+            return indent[:-self.INDENT_SPACES]
+        return ''
+    #
+    def beginFile(self, genOpts):
+        OutputGenerator.beginFile(self, genOpts)
+        # C-specific
+        #
+        # User-supplied prefix text, if any (list of strings)
+        if (genOpts.prefixText):
+            for s in genOpts.prefixText:
+                write(s, file=self.outFile)
+        #
+        # Multiple inclusion protection & C++ wrappers.
+        if (genOpts.protectFile and self.genOpts.filename):
+            headerSym = re.sub('\.h', '_H', os.path.basename(self.genOpts.filename)).upper()
+            write('#ifndef', headerSym, file=self.outFile)
+            write('#define', headerSym, '1', file=self.outFile)
+            self.newline()
+        #
+        # Headers
+        write('#include <string>', file=self.outFile)
+        self.newline()
+        write('#include "vulkan/vulkan.h"', file=self.outFile)
+        write('#include "vk_layer_extension_utils.h"', file=self.outFile)
+        write('#include "parameter_validation_utils.h"', file=self.outFile)
+        #
+        # Macros
+        self.newline()
+        write('#ifndef UNUSED_PARAMETER', file=self.outFile)
+        write('#define UNUSED_PARAMETER(x) (void)(x)', file=self.outFile)
+        write('#endif // UNUSED_PARAMETER', file=self.outFile)
+        #
+        # Namespace
+        self.newline()
+        write('namespace parameter_validation {', file = self.outFile)
+    def endFile(self):
+        # C-specific
+        self.newline()
+        # Namespace
+        write('} // namespace parameter_validation', file = self.outFile)
+        # Finish C++ wrapper and multiple inclusion protection
+        if (self.genOpts.protectFile and self.genOpts.filename):
+            self.newline()
+            write('#endif', file=self.outFile)
+        # Finish processing in superclass
+        OutputGenerator.endFile(self)
+    def beginFeature(self, interface, emit):
+        # Start processing in superclass
+        OutputGenerator.beginFeature(self, interface, emit)
+        # C-specific
+        # Accumulate includes, defines, types, enums, function pointer typedefs,
+        # end function prototypes separately for this feature. They're only
+        # printed in endFeature().
+        self.headerVersion = None
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        self.structNames = []
+        self.stypes = []
+        self.structTypes = dict()
+        self.handleTypes = set()
+        self.commands = []
+        self.structMembers = []
+        self.validatedStructs = dict()
+        self.enumRanges = dict()
+        self.flags = set()
+        self.flagBits = dict()
+    def endFeature(self):
+        # C-specific
+        # Actually write the interface to the output file.
+        if (self.emit):
+            self.newline()
+            # If type declarations are needed by other features based on
+            # this one, it may be necessary to suppress the ExtraProtect,
+            # or move it below the 'for section...' loop.
+            if (self.featureExtraProtect != None):
+                write('#ifdef', self.featureExtraProtect, file=self.outFile)
+            # Generate the struct member checking code from the captured data
+            self.processStructMemberData()
+            # Generate the command parameter checking code from the captured data
+            self.processCmdData()
+            # Write the declaration for the HeaderVersion
+            if self.headerVersion:
+                write('const uint32_t GeneratedHeaderVersion = {};'.format(self.headerVersion), file=self.outFile)
+                self.newline()
+            # Write the declarations for the VkFlags values combining all flag bits
+            for flag in sorted(self.flags):
+                flagBits = flag.replace('Flags', 'FlagBits')
+                if flagBits in self.flagBits:
+                    bits = self.flagBits[flagBits]
+                    decl = 'const {} All{} = {}'.format(flag, flagBits, bits[0])
+                    for bit in bits[1:]:
+                        decl += '|' + bit
+                    decl += ';'
+                    write(decl, file=self.outFile)
+            self.newline()
+            # Write the parameter validation code to the file
+            if (self.sections['command']):
+                if (self.genOpts.protectProto):
+                    write(self.genOpts.protectProto,
+                          self.genOpts.protectProtoStr, file=self.outFile)
+                write('\n'.join(self.sections['command']), end='', file=self.outFile)
+            if (self.featureExtraProtect != None):
+                write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
+            else:
+                self.newline()
+        # Finish processing in superclass
+        OutputGenerator.endFeature(self)
+    #
+    # Append a definition to the specified section
+    def appendSection(self, section, text):
+        # self.sections[section].append('SECTION: ' + section + '\n')
+        self.sections[section].append(text)
+    #
+    # Type generation
+    def genType(self, typeinfo, name):
+        OutputGenerator.genType(self, typeinfo, name)
+        typeElem = typeinfo.elem
+        # If the type is a struct type, traverse the imbedded <member> tags
+        # generating a structure. Otherwise, emit the tag text.
+        category = typeElem.get('category')
+        if (category == 'struct' or category == 'union'):
+            self.structNames.append(name)
+            self.genStruct(typeinfo, name)
+        elif (category == 'handle'):
+            self.handleTypes.add(name)
+        elif (category == 'bitmask'):
+            self.flags.add(name)
+        elif (category == 'define'):
+            if name == 'VK_HEADER_VERSION':
+                nameElem = typeElem.find('name')
+                self.headerVersion = noneStr(nameElem.tail).strip()
+    #
+    # Struct parameter check generation.
+    # This is a special case of the <type> tag where the contents are
+    # interpreted as a set of <member> tags instead of freeform C
+    # C type declarations. The <member> tags are just like <param>
+    # tags - they are a declaration of a struct or union member.
+    # Only simple member declarations are supported (no nested
+    # structs etc.)
+    def genStruct(self, typeinfo, typeName):
+        OutputGenerator.genStruct(self, typeinfo, typeName)
+        conditions = self.structMemberValidationConditions[typeName] if typeName in self.structMemberValidationConditions else None
+        members = typeinfo.elem.findall('.//member')
+        #
+        # Iterate over members once to get length parameters for arrays
+        lens = set()
+        for member in members:
+            len = self.getLen(member)
+            if len:
+                lens.add(len)
+        #
+        # Generate member info
+        membersInfo = []
+        for member in members:
+            # Get the member's type and name
+            info = self.getTypeNameTuple(member)
+            type = info[0]
+            name = info[1]
+            stypeValue = ''
+            cdecl = self.makeCParamDecl(member, 0)
+            # Process VkStructureType
+            if type == 'VkStructureType':
+                # Extract the required struct type value from the comments
+                # embedded in the original text defining the 'typeinfo' element
+                rawXml = etree.tostring(typeinfo.elem).decode('ascii')
+                result = re.search(r'VK_STRUCTURE_TYPE_\w+', rawXml)
+                if result:
+                    value = result.group(0)
+                else:
+                    value = self.genVkStructureType(typeName)
+                # Store the required type value
+                self.structTypes[typeName] = self.StructType(name=name, value=value)
+            #
+            # Store pointer/array/string info
+            # Check for parameter name in lens set
+            iscount = False
+            if name in lens:
+                iscount = True
+            # The pNext members are not tagged as optional, but are treated as
+            # optional for parameter NULL checks.  Static array members
+            # are also treated as optional to skip NULL pointer validation, as
+            # they won't be NULL.
+            isstaticarray = self.paramIsStaticArray(member)
+            isoptional = False
+            if self.paramIsOptional(member) or (name == 'pNext') or (isstaticarray):
+                isoptional = True
+            membersInfo.append(self.CommandParam(type=type, name=name,
+                                                ispointer=self.paramIsPointer(member),
+                                                isstaticarray=isstaticarray,
+                                                isbool=True if type == 'VkBool32' else False,
+                                                israngedenum=True if type in self.enumRanges else False,
+                                                isconst=True if 'const' in cdecl else False,
+                                                isoptional=isoptional,
+                                                iscount=iscount,
+                                                noautovalidity=True if member.attrib.get('noautovalidity') is not None else False,
+                                                len=self.getLen(member),
+                                                extstructs=member.attrib.get('validextensionstructs') if name == 'pNext' else None,
+                                                condition=conditions[name] if conditions and name in conditions else None,
+                                                cdecl=cdecl))
+        self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo))
+    #
+    # Capture group (e.g. C "enum" type) info to be used for
+    # param check code generation.
+    # These are concatenated together with other types.
+    def genGroup(self, groupinfo, groupName):
+        OutputGenerator.genGroup(self, groupinfo, groupName)
+        groupElem = groupinfo.elem
+        #
+        # Store the sType values
+        if groupName == 'VkStructureType':
+            for elem in groupElem.findall('enum'):
+                self.stypes.append(elem.get('name'))
+        elif 'FlagBits' in groupName:
+            bits = []
+            for elem in groupElem.findall('enum'):
+                bits.append(elem.get('name'))
+            if bits:
+                self.flagBits[groupName] = bits
+        else:
+            # Determine if begin/end ranges are needed (we don't do this for VkStructureType, which has a more finely grained check)
+            expandName = re.sub(r'([0-9a-z_])([A-Z0-9][^A-Z0-9]?)',r'\1_\2',groupName).upper()
+            expandPrefix = expandName
+            expandSuffix = ''
+            expandSuffixMatch = re.search(r'[A-Z][A-Z]+$',groupName)
+            if expandSuffixMatch:
+                expandSuffix = '_' + expandSuffixMatch.group()
+                # Strip off the suffix from the prefix
+                expandPrefix = expandName.rsplit(expandSuffix, 1)[0]
+            isEnum = ('FLAG_BITS' not in expandPrefix)
+            if isEnum:
+                self.enumRanges[groupName] = (expandPrefix + '_BEGIN_RANGE' + expandSuffix, expandPrefix + '_END_RANGE' + expandSuffix)
+    #
+    # Capture command parameter info to be used for param
+    # check code generation.
+    def genCmd(self, cmdinfo, name):
+        OutputGenerator.genCmd(self, cmdinfo, name)
+        if name not in self.blacklist:
+            params = cmdinfo.elem.findall('param')
+            # Get list of array lengths
+            lens = set()
+            for param in params:
+                len = self.getLen(param)
+                if len:
+                    lens.add(len)
+            # Get param info
+            paramsInfo = []
+            for param in params:
+                paramInfo = self.getTypeNameTuple(param)
+                cdecl = self.makeCParamDecl(param, 0)
+                # Check for parameter name in lens set
+                iscount = False
+                if paramInfo[1] in lens:
+                    iscount = True
+                paramsInfo.append(self.CommandParam(type=paramInfo[0], name=paramInfo[1],
+                                                    ispointer=self.paramIsPointer(param),
+                                                    isstaticarray=self.paramIsStaticArray(param),
+                                                    isbool=True if paramInfo[0] == 'VkBool32' else False,
+                                                    israngedenum=True if paramInfo[0] in self.enumRanges else False,
+                                                    isconst=True if 'const' in cdecl else False,
+                                                    isoptional=self.paramIsOptional(param),
+                                                    iscount=iscount,
+                                                    noautovalidity=True if param.attrib.get('noautovalidity') is not None else False,
+                                                    len=self.getLen(param),
+                                                    extstructs=None,
+                                                    condition=None,
+                                                    cdecl=cdecl))
+            self.commands.append(self.CommandData(name=name, params=paramsInfo, cdecl=self.makeCDecls(cmdinfo.elem)[0]))
+    #
+    # Check if the parameter passed in is a pointer
+    def paramIsPointer(self, param):
+        ispointer = 0
+        paramtype = param.find('type')
+        if (paramtype.tail is not None) and ('*' in paramtype.tail):
+            ispointer = paramtype.tail.count('*')
+        elif paramtype.text[:4] == 'PFN_':
+            # Treat function pointer typedefs as a pointer to a single value
+            ispointer = 1
+        return ispointer
+    #
+    # Check if the parameter passed in is a static array
+    def paramIsStaticArray(self, param):
+        isstaticarray = 0
+        paramname = param.find('name')
+        if (paramname.tail is not None) and ('[' in paramname.tail):
+            isstaticarray = paramname.tail.count('[')
+        return isstaticarray
+    #
+    # Check if the parameter passed in is optional
+    # Returns a list of Boolean values for comma separated len attributes (len='false,true')
+    def paramIsOptional(self, param):
+        # See if the handle is optional
+        isoptional = False
+        # Simple, if it's optional, return true
+        optString = param.attrib.get('optional')
+        if optString:
+            if optString == 'true':
+                isoptional = True
+            elif ',' in optString:
+                opts = []
+                for opt in optString.split(','):
+                    val = opt.strip()
+                    if val == 'true':
+                        opts.append(True)
+                    elif val == 'false':
+                        opts.append(False)
+                    else:
+                        print('Unrecognized len attribute value',val)
+                isoptional = opts
+        return isoptional
+    #
+    # Check if the handle passed in is optional
+    # Uses the same logic as ValidityOutputGenerator.isHandleOptional
+    def isHandleOptional(self, param, lenParam):
+        # Simple, if it's optional, return true
+        if param.isoptional:
+            return True
+        # If no validity is being generated, it usually means that validity is complex and not absolute, so let's say yes.
+        if param.noautovalidity:
+            return True
+        # If the parameter is an array and we haven't already returned, find out if any of the len parameters are optional
+        if lenParam and lenParam.isoptional:
+            return True
+        return False
+    #
+    # Generate a VkStructureType based on a structure typename
+    def genVkStructureType(self, typename):
+        # Add underscore between lowercase then uppercase
+        value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', typename)
+        # Change to uppercase
+        value = value.upper()
+        # Add STRUCTURE_TYPE_
+        return re.sub('VK_', 'VK_STRUCTURE_TYPE_', value)
+    #
+    # Get the cached VkStructureType value for the specified struct typename, or generate a VkStructureType
+    # value assuming the struct is defined by a different feature
+    def getStructType(self, typename):
+        value = None
+        if typename in self.structTypes:
+            value = self.structTypes[typename].value
+        else:
+            value = self.genVkStructureType(typename)
+            self.logMsg('diag', 'ParameterValidation: Generating {} for {} structure type that was not defined by the current feature'.format(value, typename))
+        return value
+    #
+    # Retrieve the value of the len tag
+    def getLen(self, param):
+        result = None
+        len = param.attrib.get('len')
+        if len and len != 'null-terminated':
+            # For string arrays, 'len' can look like 'count,null-terminated',
+            # indicating that we have a null terminated array of strings.  We
+            # strip the null-terminated from the 'len' field and only return
+            # the parameter specifying the string count
+            if 'null-terminated' in len:
+                result = len.split(',')[0]
+            else:
+                result = len
+            result = str(result).replace('::', '->')
+        return result
+    #
+    # Retrieve the type and name for a parameter
+    def getTypeNameTuple(self, param):
+        type = ''
+        name = ''
+        for elem in param:
+            if elem.tag == 'type':
+                type = noneStr(elem.text)
+            elif elem.tag == 'name':
+                name = noneStr(elem.text)
+        return (type, name)
+    #
+    # Find a named parameter in a parameter list
+    def getParamByName(self, params, name):
+        for param in params:
+            if param.name == name:
+                return param
+        return None
+    #
+    # Extract length values from latexmath.  Currently an inflexible solution that looks for specific
+    # patterns that are found in vk.xml.  Will need to be updated when new patterns are introduced.
+    def parseLateXMath(self, source):
+        name = 'ERROR'
+        decoratedName = 'ERROR'
+        if 'mathit' in source:
+            # Matches expressions similar to 'latexmath:[$\lceil{\mathit{rasterizationSamples} \over 32}\rceil$]'
+            match = re.match(r'latexmath\s*\:\s*\[\s*\$\\l(\w+)\s*\{\s*\\mathit\s*\{\s*(\w+)\s*\}\s*\\over\s*(\d+)\s*\}\s*\\r(\w+)\$\s*\]', source)
+            if not match or match.group(1) != match.group(4):
+                raise 'Unrecognized latexmath expression'
+            name = match.group(2)
+            decoratedName = '{}({}/{})'.format(*match.group(1, 2, 3))
+        else:
+            # Matches expressions similar to 'latexmath : [$dataSize \over 4$]'
+            match = re.match(r'latexmath\s*\:\s*\[\s*\$\s*(\w+)\s*\\over\s*(\d+)\s*\$\s*\]', source)
+            name = match.group(1)
+            decoratedName = '{}/{}'.format(*match.group(1, 2))
+        return name, decoratedName
+    #
+    # Get the length paramater record for the specified parameter name
+    def getLenParam(self, params, name):
+        lenParam = None
+        if name:
+            if '->' in name:
+                # The count is obtained by dereferencing a member of a struct parameter
+                lenParam = self.CommandParam(name=name, iscount=True, ispointer=False, isbool=False, israngedenum=False, isconst=False,
+                                             isstaticarray=None, isoptional=False, type=None, noautovalidity=False, len=None, extstructs=None,
+                                             condition=None, cdecl=None)
+            elif 'latexmath' in name:
+                lenName, decoratedName = self.parseLateXMath(name)
+                lenParam = self.getParamByName(params, lenName)
+                # TODO: Zero-check the result produced by the equation?
+                # Copy the stored len parameter entry and overwrite the name with the processed latexmath equation
+                #param = self.getParamByName(params, lenName)
+                #lenParam = self.CommandParam(name=decoratedName, iscount=param.iscount, ispointer=param.ispointer,
+                #                             isoptional=param.isoptional, type=param.type, len=param.len,
+                #                             isstaticarray=param.isstaticarray, extstructs=param.extstructs,
+                #                             noautovalidity=True, condition=None, cdecl=param.cdecl)
+            else:
+                lenParam = self.getParamByName(params, name)
+        return lenParam
+    #
+    # Convert a vulkan.h command declaration into a parameter_validation.h definition
+    def getCmdDef(self, cmd):
+        #
+        # Strip the trailing ';' and split into individual lines
+        lines = cmd.cdecl[:-1].split('\n')
+        # Replace Vulkan prototype
+        lines[0] = 'static bool parameter_validation_' + cmd.name + '('
+        # Replace the first argument with debug_report_data, when the first
+        # argument is a handle (not vkCreateInstance)
+        reportData = '    debug_report_data*'.ljust(self.genOpts.alignFuncParam) + 'report_data,'
+        if cmd.name != 'vkCreateInstance':
+            lines[1] = reportData
+        else:
+            lines.insert(1, reportData)
+        return '\n'.join(lines)
+    #
+    # Generate the code to check for a NULL dereference before calling the
+    # validation function
+    def genCheckedLengthCall(self, name, exprs):
+        count = name.count('->')
+        if count:
+            checkedExpr = []
+            localIndent = ''
+            elements = name.split('->')
+            # Open the if expression blocks
+            for i in range(0, count):
+                checkedExpr.append(localIndent + 'if ({} != NULL) {{\n'.format('->'.join(elements[0:i+1])))
+                localIndent = self.incIndent(localIndent)
+            # Add the validation expression
+            for expr in exprs:
+                checkedExpr.append(localIndent + expr)
+            # Close the if blocks
+            for i in range(0, count):
+                localIndent = self.decIndent(localIndent)
+                checkedExpr.append(localIndent + '}\n')
+            return [checkedExpr]
+        # No if statements were required
+        return exprs
+    #
+    # Generate code to check for a specific condition before executing validation code
+    def genConditionalCall(self, prefix, condition, exprs):
+        checkedExpr = []
+        localIndent = ''
+        formattedCondition = condition.format(prefix)
+        checkedExpr.append(localIndent + 'if ({})\n'.format(formattedCondition))
+        checkedExpr.append(localIndent + '{\n')
+        localIndent = self.incIndent(localIndent)
+        for expr in exprs:
+            checkedExpr.append(localIndent + expr)
+        localIndent = self.decIndent(localIndent)
+        checkedExpr.append(localIndent + '}\n')
+        return [checkedExpr]
+    #
+    # Generate the sType check string
+    def makeStructTypeCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, lenPtrRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
+        checkExpr = []
+        stype = self.structTypes[value.type]
+        if lenValue:
+            # This is an array with a pointer to a count value
+            if lenValue.ispointer:
+                # When the length parameter is a pointer, there is an extra Boolean parameter in the function call to indicate if it is required
+                checkExpr.append('skipCall |= validate_struct_type_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, "{sv}", {pf}{ln}, {pf}{vn}, {sv}, {}, {}, {});\n'.format(
+                    funcPrintName, lenPtrRequired, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, sv=stype.value, pf=prefix, **postProcSpec))
+            # This is an array with an integer count value
+            else:
+                checkExpr.append('skipCall |= validate_struct_type_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, "{sv}", {pf}{ln}, {pf}{vn}, {sv}, {}, {});\n'.format(
+                    funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, sv=stype.value, pf=prefix, **postProcSpec))
+        # This is an individual struct
+        else:
+            checkExpr.append('skipCall |= validate_struct_type(report_data, "{}", {ppp}"{}"{pps}, "{sv}", {}{vn}, {sv}, {});\n'.format(
+                funcPrintName, valuePrintName, prefix, valueRequired, vn=value.name, sv=stype.value, **postProcSpec))
+        return checkExpr
+    #
+    # Generate the handle check string
+    def makeHandleCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
+        checkExpr = []
+        if lenValue:
+            if lenValue.ispointer:
+                # This is assumed to be an output array with a pointer to a count value
+                raise('Unsupported parameter validation case: Output handle array elements are not NULL checked')
+            else:
+                # This is an array with an integer count value
+                checkExpr.append('skipCall |= validate_handle_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(
+                    funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
+        else:
+            # This is assumed to be an output handle pointer
+            raise('Unsupported parameter validation case: Output handles are not NULL checked')
+        return checkExpr
+    #
+    # Generate check string for an array of VkFlags values
+    def makeFlagsArrayCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
+        checkExpr = []
+        flagBitsName = value.type.replace('Flags', 'FlagBits')
+        if not flagBitsName in self.flagBits:
+            raise('Unsupported parameter validation case: array of reserved VkFlags')
+        else:
+            allFlags = 'All' + flagBitsName
+            checkExpr.append('skipCall |= validate_flags_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, "{}", {}, {pf}{}, {pf}{}, {}, {});\n'.format(funcPrintName, lenPrintName, valuePrintName, flagBitsName, allFlags, lenValue.name, value.name, lenValueRequired, valueRequired, pf=prefix, **postProcSpec))
+        return checkExpr
+    #
+    # Generate pNext check string
+    def makeStructNextCheck(self, prefix, value, funcPrintName, valuePrintName, postProcSpec):
+        checkExpr = []
+        # Generate an array of acceptable VkStructureType values for pNext
+        extStructCount = 0
+        extStructVar = 'NULL'
+        extStructNames = 'NULL'
+        if value.extstructs:
+            structs = value.extstructs.split(',')
+            checkExpr.append('const VkStructureType allowedStructs[] = {' + ', '.join([self.getStructType(s) for s in structs]) + '};\n')
+            extStructCount = 'ARRAY_SIZE(allowedStructs)'
+            extStructVar = 'allowedStructs'
+            extStructNames = '"' + ', '.join(structs) + '"'
+        checkExpr.append('skipCall |= validate_struct_pnext(report_data, "{}", {ppp}"{}"{pps}, {}, {}{}, {}, {}, GeneratedHeaderVersion);\n'.format(
+            funcPrintName, valuePrintName, extStructNames, prefix, value.name, extStructCount, extStructVar, **postProcSpec))
+        return checkExpr
+    #
+    # Generate the pointer check string
+    def makePointerCheck(self, prefix, value, lenValue, valueRequired, lenValueRequired, lenPtrRequired, funcPrintName, lenPrintName, valuePrintName, postProcSpec):
+        checkExpr = []
+        if lenValue:
+            # This is an array with a pointer to a count value
+            if lenValue.ispointer:
+                # If count and array parameters are optional, there will be no validation
+                if valueRequired == 'true' or lenPtrRequired == 'true' or lenValueRequired == 'true':
+                    # When the length parameter is a pointer, there is an extra Boolean parameter in the function call to indicate if it is required
+                    checkExpr.append('skipCall |= validate_array(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {}, {});\n'.format(
+                        funcPrintName, lenPtrRequired, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
+            # This is an array with an integer count value
+            else:
+                # If count and array parameters are optional, there will be no validation
+                if valueRequired == 'true' or lenValueRequired == 'true':
+                    # Arrays of strings receive special processing
+                    validationFuncName = 'validate_array' if value.type != 'char' else 'validate_string_array'
+                    checkExpr.append('skipCall |= {}(report_data, "{}", {ppp}"{ldn}"{pps}, {ppp}"{dn}"{pps}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(
+                        validationFuncName, funcPrintName, lenValueRequired, valueRequired, ln=lenValue.name, ldn=lenPrintName, dn=valuePrintName, vn=value.name, pf=prefix, **postProcSpec))
+            if checkExpr:
+                if lenValue and ('->' in lenValue.name):
+                    # Add checks to ensure the validation call does not dereference a NULL pointer to obtain the count
+                    checkExpr = self.genCheckedLengthCall(lenValue.name, checkExpr)
+        # This is an individual struct that is not allowed to be NULL
+        elif not value.isoptional:
+            # Function pointers need a reinterpret_cast to void*
+            if value.type[:4] == 'PFN_':
+                checkExpr.append('skipCall |= validate_required_pointer(report_data, "{}", {ppp}"{}"{pps}, reinterpret_cast<const void*>({}{}));\n'.format(funcPrintName, valuePrintName, prefix, value.name, **postProcSpec))
+            else:
+                checkExpr.append('skipCall |= validate_required_pointer(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcPrintName, valuePrintName, prefix, value.name, **postProcSpec))
+        return checkExpr
+    #
+    # Process struct member validation code, performing name suibstitution if required
+    def processStructMemberCode(self, line, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec):
+        # Build format specifier list
+        kwargs = {}
+        if '{postProcPrefix}' in line:
+            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
+            if type(memberDisplayNamePrefix) is tuple:
+                kwargs['postProcPrefix'] = 'ParameterName('
+            else:
+                kwargs['postProcPrefix'] = postProcSpec['ppp']
+        if '{postProcSuffix}' in line:
+            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
+            if type(memberDisplayNamePrefix) is tuple:
+                kwargs['postProcSuffix'] = ', ParameterName::IndexVector{{ {}{} }})'.format(postProcSpec['ppi'], memberDisplayNamePrefix[1])
+            else:
+                kwargs['postProcSuffix'] = postProcSpec['pps']
+        if '{postProcInsert}' in line:
+            # If we have a tuple that includes a format string and format parameters, need to use ParameterName class
+            if type(memberDisplayNamePrefix) is tuple:
+                kwargs['postProcInsert'] = '{}{}, '.format(postProcSpec['ppi'], memberDisplayNamePrefix[1])
+            else:
+                kwargs['postProcInsert'] = postProcSpec['ppi']
+        if '{funcName}' in line:
+            kwargs['funcName'] = funcName
+        if '{valuePrefix}' in line:
+            kwargs['valuePrefix'] = memberNamePrefix
+        if '{displayNamePrefix}' in line:
+            # Check for a tuple that includes a format string and format parameters to be used with the ParameterName class
+            if type(memberDisplayNamePrefix) is tuple:
+                kwargs['displayNamePrefix'] = memberDisplayNamePrefix[0]
+            else:
+                kwargs['displayNamePrefix'] = memberDisplayNamePrefix
+
+        if kwargs:
+            # Need to escape the C++ curly braces
+            if 'IndexVector' in line:
+                line = line.replace('IndexVector{ ', 'IndexVector{{ ')
+                line = line.replace(' }),', ' }}),')
+            return line.format(**kwargs)
+        return line
+    #
+    # Process struct validation code for inclusion in function or parent struct validation code
+    def expandStructCode(self, lines, funcName, memberNamePrefix, memberDisplayNamePrefix, indent, output, postProcSpec):
+        for line in lines:
+            if output:
+                output[-1] += '\n'
+            if type(line) is list:
+                for sub in line:
+                    output.append(self.processStructMemberCode(indent + sub, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec))
+            else:
+                output.append(self.processStructMemberCode(indent + line, funcName, memberNamePrefix, memberDisplayNamePrefix, postProcSpec))
+        return output
+    #
+    # Process struct pointer/array validation code, perfoeming name substitution if required
+    def expandStructPointerCode(self, prefix, value, lenValue, funcName, valueDisplayName, postProcSpec):
+        expr = []
+        expr.append('if ({}{} != NULL)\n'.format(prefix, value.name))
+        expr.append('{')
+        indent = self.incIndent(None)
+        if lenValue:
+            # Need to process all elements in the array
+            indexName = lenValue.name.replace('Count', 'Index')
+            expr[-1] += '\n'
+            expr.append(indent + 'for (uint32_t {iname} = 0; {iname} < {}{}; ++{iname})\n'.format(prefix, lenValue.name, iname=indexName))
+            expr.append(indent + '{')
+            indent = self.incIndent(indent)
+            # Prefix for value name to display in error message
+            memberNamePrefix = '{}{}[{}].'.format(prefix, value.name, indexName)
+            memberDisplayNamePrefix = ('{}[%i].'.format(valueDisplayName), indexName)
+        else:
+            memberNamePrefix = '{}{}->'.format(prefix, value.name)
+            memberDisplayNamePrefix = '{}->'.format(valueDisplayName)
+        #
+        # Expand the struct validation lines
+        expr = self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, indent, expr, postProcSpec)
+        #
+        if lenValue:
+            # Close if and for scopes
+            indent = self.decIndent(indent)
+            expr.append(indent + '}\n')
+        expr.append('}\n')
+        return expr
+    #
+    # Generate the parameter checking code
+    def genFuncBody(self, funcName, values, valuePrefix, displayNamePrefix, structTypeName):
+        lines = []    # Generated lines of code
+        unused = []   # Unused variable names
+        for value in values:
+            usedLines = []
+            lenParam = None
+            #
+            # Prefix and suffix for post processing of parameter names for struct members.  Arrays of structures need special processing to include the array index in the full parameter name.
+            postProcSpec = {}
+            postProcSpec['ppp'] = '' if not structTypeName else '{postProcPrefix}'
+            postProcSpec['pps'] = '' if not structTypeName else '{postProcSuffix}'
+            postProcSpec['ppi'] = '' if not structTypeName else '{postProcInsert}'
+            #
+            # Generate the full name of the value, which will be printed in the error message, by adding the variable prefix to the value name
+            valueDisplayName = '{}{}'.format(displayNamePrefix, value.name)
+            #
+            # Check for NULL pointers, ignore the inout count parameters that
+            # will be validated with their associated array
+            if (value.ispointer or value.isstaticarray) and not value.iscount:
+                #
+                # Parameters for function argument generation
+                req = 'true'    # Paramerter cannot be NULL
+                cpReq = 'true'  # Count pointer cannot be NULL
+                cvReq = 'true'  # Count value cannot be 0
+                lenDisplayName = None # Name of length parameter to print with validation messages; parameter name with prefix applied
+                #
+                # Generate required/optional parameter strings for the pointer and count values
+                if value.isoptional:
+                    req = 'false'
+                if value.len:
+                    # The parameter is an array with an explicit count parameter
+                    lenParam = self.getLenParam(values, value.len)
+                    lenDisplayName = '{}{}'.format(displayNamePrefix, lenParam.name)
+                    if lenParam.ispointer:
+                        # Count parameters that are pointers are inout
+                        if type(lenParam.isoptional) is list:
+                            if lenParam.isoptional[0]:
+                                cpReq = 'false'
+                            if lenParam.isoptional[1]:
+                                cvReq = 'false'
+                        else:
+                            if lenParam.isoptional:
+                                cpReq = 'false'
+                    else:
+                        if lenParam.isoptional:
+                            cvReq = 'false'
+                #
+                # The parameter will not be processes when tagged as 'noautovalidity'
+                # For the pointer to struct case, the struct pointer will not be validated, but any
+                # members not tagged as 'noatuvalidity' will be validated
+                if value.noautovalidity:
+                    # Log a diagnostic message when validation cannot be automatically generated and must be implemented manually
+                    self.logMsg('diag', 'ParameterValidation: No validation for {} {}'.format(structTypeName if structTypeName else funcName, value.name))
+                else:
+                    #
+                    # If this is a pointer to a struct with an sType field, verify the type
+                    if value.type in self.structTypes:
+                        usedLines += self.makeStructTypeCheck(valuePrefix, value, lenParam, req, cvReq, cpReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
+                    # If this is an input handle array that is not allowed to contain NULL handles, verify that none of the handles are VK_NULL_HANDLE
+                    elif value.type in self.handleTypes and value.isconst and not self.isHandleOptional(value, lenParam):
+                        usedLines += self.makeHandleCheck(valuePrefix, value, lenParam, req, cvReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
+                    elif value.type in self.flags and value.isconst:
+                        usedLines += self.makeFlagsArrayCheck(valuePrefix, value, lenParam, req, cvReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
+                    elif value.isbool and value.isconst:
+                        usedLines.append('skipCall |= validate_bool32_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, {pf}{}, {pf}{}, {}, {});\n'.format(funcName, lenDisplayName, valueDisplayName, lenParam.name, value.name, cvReq, req, pf=valuePrefix, **postProcSpec))
+                    elif value.israngedenum and value.isconst:
+                        enumRange = self.enumRanges[value.type]
+                        usedLines.append('skipCall |= validate_ranged_enum_array(report_data, "{}", {ppp}"{}"{pps}, {ppp}"{}"{pps}, "{}", {}, {}, {pf}{}, {pf}{}, {}, {});\n'.format(funcName, lenDisplayName, valueDisplayName, value.type, enumRange[0], enumRange[1], lenParam.name, value.name, cvReq, req, pf=valuePrefix, **postProcSpec))
+                    elif value.name == 'pNext':
+                        # We need to ignore VkDeviceCreateInfo and VkInstanceCreateInfo, as the loader manipulates them in a way that is not documented in vk.xml
+                        if not structTypeName in ['VkDeviceCreateInfo', 'VkInstanceCreateInfo']:
+                            usedLines += self.makeStructNextCheck(valuePrefix, value, funcName, valueDisplayName, postProcSpec)
+                    else:
+                        usedLines += self.makePointerCheck(valuePrefix, value, lenParam, req, cvReq, cpReq, funcName, lenDisplayName, valueDisplayName, postProcSpec)
+                    #
+                    # If this is a pointer to a struct (input), see if it contains members that need to be checked
+                    if value.type in self.validatedStructs and value.isconst:
+                        usedLines.append(self.expandStructPointerCode(valuePrefix, value, lenParam, funcName, valueDisplayName, postProcSpec))
+            # Non-pointer types
+            else:
+                #
+                # The parameter will not be processes when tagged as 'noautovalidity'
+                # For the struct case, the struct type will not be validated, but any
+                # members not tagged as 'noatuvalidity' will be validated
+                if value.noautovalidity:
+                    # Log a diagnostic message when validation cannot be automatically generated and must be implemented manually
+                    self.logMsg('diag', 'ParameterValidation: No validation for {} {}'.format(structTypeName if structTypeName else funcName, value.name))
+                else:
+                    if value.type in self.structTypes:
+                        stype = self.structTypes[value.type]
+                        usedLines.append('skipCall |= validate_struct_type(report_data, "{}", {ppp}"{}"{pps}, "{sv}", &({}{vn}), {sv}, false);\n'.format(
+                            funcName, valueDisplayName, valuePrefix, vn=value.name, sv=stype.value, **postProcSpec))
+                    elif value.type in self.handleTypes:
+                        if not self.isHandleOptional(value, None):
+                            usedLines.append('skipCall |= validate_required_handle(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcName, valueDisplayName, valuePrefix, value.name, **postProcSpec))
+                    elif value.type in self.flags:
+                        flagBitsName = value.type.replace('Flags', 'FlagBits')
+                        if not flagBitsName in self.flagBits:
+                            usedLines.append('skipCall |= validate_reserved_flags(report_data, "{}", {ppp}"{}"{pps}, {pf}{});\n'.format(funcName, valueDisplayName, value.name, pf=valuePrefix, **postProcSpec))
+                        else:
+                            flagsRequired = 'false' if value.isoptional else 'true'
+                            allFlagsName = 'All' + flagBitsName
+                            usedLines.append('skipCall |= validate_flags(report_data, "{}", {ppp}"{}"{pps}, "{}", {}, {pf}{}, {});\n'.format(funcName, valueDisplayName, flagBitsName, allFlagsName, value.name, flagsRequired, pf=valuePrefix, **postProcSpec))
+                    elif value.isbool:
+                        usedLines.append('skipCall |= validate_bool32(report_data, "{}", {ppp}"{}"{pps}, {}{});\n'.format(funcName, valueDisplayName, valuePrefix, value.name, **postProcSpec))
+                    elif value.israngedenum:
+                        enumRange = self.enumRanges[value.type]
+                        usedLines.append('skipCall |= validate_ranged_enum(report_data, "{}", {ppp}"{}"{pps}, "{}", {}, {}, {}{});\n'.format(funcName, valueDisplayName, value.type, enumRange[0], enumRange[1], valuePrefix, value.name, **postProcSpec))
+                    #
+                    # If this is a struct, see if it contains members that need to be checked
+                    if value.type in self.validatedStructs:
+                        memberNamePrefix = '{}{}.'.format(valuePrefix, value.name)
+                        memberDisplayNamePrefix = '{}.'.format(valueDisplayName)
+                        usedLines.append(self.expandStructCode(self.validatedStructs[value.type], funcName, memberNamePrefix, memberDisplayNamePrefix, '', [], postProcSpec))
+            #
+            # Append the parameter check to the function body for the current command
+            if usedLines:
+                # Apply special conditional checks
+                if value.condition:
+                    usedLines = self.genConditionalCall(valuePrefix, value.condition, usedLines)
+                lines += usedLines
+            elif not value.iscount:
+                # If no expression was generated for this value, it is unreferenced by the validation function, unless
+                # it is an array count, which is indirectly referenced for array valiadation.
+                unused.append(value.name)
+        return lines, unused
+    #
+    # Generate the struct member check code from the captured data
+    def processStructMemberData(self):
+        indent = self.incIndent(None)
+        for struct in self.structMembers:
+            #
+            # The string returned by genFuncBody will be nested in an if check for a NULL pointer, so needs its indent incremented
+            lines, unused = self.genFuncBody('{funcName}', struct.members, '{valuePrefix}', '{displayNamePrefix}', struct.name)
+            if lines:
+                self.validatedStructs[struct.name] = lines
+    #
+    # Generate the command param check code from the captured data
+    def processCmdData(self):
+        indent = self.incIndent(None)
+        for command in self.commands:
+            # Skip first parameter if it is a dispatch handle (everything except vkCreateInstance)
+            startIndex = 0 if command.name == 'vkCreateInstance' else 1
+            lines, unused = self.genFuncBody(command.name, command.params[startIndex:], '', '', None)
+            if lines:
+                cmdDef = self.getCmdDef(command) + '\n'
+                cmdDef += '{\n'
+                # Process unused parameters, Ignoring the first dispatch handle parameter, which is not
+                # processed by parameter_validation (except for vkCreateInstance, which does not have a
+                # handle as its first parameter)
+                if unused:
+                    for name in unused:
+                        cmdDef += indent + 'UNUSED_PARAMETER({});\n'.format(name)
+                    if len(unused) > 0:
+                        cmdDef += '\n'
+                cmdDef += indent + 'bool skipCall = false;\n'
+                for line in lines:
+                    cmdDef += '\n'
+                    if type(line) is list:
+                        for sub in line:
+                            cmdDef += indent + sub
+                    else:
+                        cmdDef += indent + line
+                cmdDef += '\n'
+                cmdDef += indent + 'return skipCall;\n'
+                cmdDef += '}\n'
+                self.appendSection('command', cmdDef)
diff --git a/reg.py b/reg.py
index 55b513c..98436a3 100755
--- a/reg.py
+++ b/reg.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python3 -i
 #
-# Copyright (c) 2013-2015 The Khronos Group Inc.
+# Copyright (c) 2013-2016 The Khronos Group Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import io,os,re,string,sys
+import io,os,re,string,sys,copy
 import xml.etree.ElementTree as etree
 
 # matchAPIProfile - returns whether an API and profile
@@ -89,6 +89,12 @@
     """Represents the state of a registry type"""
     def __init__(self, elem):
         BaseInfo.__init__(self, elem)
+        self.additionalValidity = []
+        self.removedValidity = []
+    def resetState(self):
+        BaseInfo.resetState(self)
+        self.additionalValidity = []
+        self.removedValidity = []
 
 # GroupInfo - registry information about a group of related enums
 # in an <enums> block, generally corresponding to a C "enum" type.
@@ -113,10 +119,16 @@
     """Represents the state of a registry command"""
     def __init__(self, elem):
         BaseInfo.__init__(self, elem)
+        self.additionalValidity = []
+        self.removedValidity = []
+    def resetState(self):
+        BaseInfo.resetState(self)
+        self.additionalValidity = []
+        self.removedValidity = []
 
 # FeatureInfo - registry information about an API <feature>
 # or <extension>
-#   name - feature name string (e.g. 'vk_ext_khr_surface')
+#   name - feature name string (e.g. 'VK_KHR_surface')
 #   version - feature version number (e.g. 1.2). <extension>
 #     features are unversioned and assigned version number 0.
 #     ** This is confusingly taken from the 'number' attribute of <feature>.
@@ -137,10 +149,12 @@
             self.category = 'VERSION'
             self.version = elem.get('number')
             self.number = "0"
+            self.supported = None
         else:
             self.category = self.name.split('_', 2)[1]
             self.version = "0"
             self.number = elem.get('number')
+            self.supported = elem.get('supported')
         self.emit = False
 
 from generator import write, GeneratorOptions, OutputGenerator
@@ -203,7 +217,7 @@
     def setGenerator(self, gen):
         """Specify output generator object. None restores the default generator"""
         self.gen = gen
-        self.gen.setRegistry(self.tree)
+        self.gen.setRegistry(self)
 
     # addElementInfo - add information about an element to the
     # corresponding dictionary
@@ -314,10 +328,23 @@
 
             # Add additional enums defined only in <extension> tags
             # to the corresponding core type.
-            # When seen here, a copy, processed to contain the numeric enum
-            # value, is added to the corresponding <enums> element, as well
-            # as adding to the enum dictionary. Also add a 'extnumber'
-            # attribute containing the extension number.
+            # When seen here, the <enum> element, processed to contain the
+            # numeric enum value, is added to the corresponding <enums>
+            # element, as well as adding to the enum dictionary. It is
+            # *removed* from the <require> element it is introduced in.
+            # Not doing this will cause spurious genEnum()
+            # calls to be made in output generation, and it's easier
+            # to handle here than in genEnum().
+            #
+            # In lxml.etree, an Element can have only one parent, so the
+            # append() operation also removes the element. But in Python's
+            # ElementTree package, an Element can have multiple parents. So
+            # it must be explicitly removed from the <require> tag, leading
+            # to the nested loop traversal of <require>/<enum> elements
+            # below.
+            #
+            # This code also adds a 'extnumber' attribute containing the
+            # extension number, used for enumerant value calculation.
             #
             # For <enum> tags which are actually just constants, if there's
             # no 'extends' tag but there is a 'value' or 'bitpos' tag, just
@@ -328,7 +355,9 @@
             # Something like this will need to be done for 'feature's up
             # above, if we use the same mechanism for adding to the core
             # API in 1.1.
-            for enum in feature.findall('require/enum'):
+            #
+            for elem in feature.findall('require'):
+              for enum in elem.findall('enum'):
                 addEnumInfo = False
                 groupName = enum.get('extends')
                 if (groupName != None):
@@ -336,12 +365,17 @@
                     #     enum.get('name'))
                     # Add extension number attribute to the <enum> element
                     enum.attrib['extnumber'] = featureInfo.number
+                    enum.attrib['extname'] = featureInfo.name
+                    enum.attrib['supported'] = featureInfo.supported
                     # Look up the GroupInfo with matching groupName
                     if (groupName in self.groupdict.keys()):
                         # self.gen.logMsg('diag', '*** Matching group',
                         #     groupName, 'found, adding element...')
                         gi = self.groupdict[groupName]
                         gi.elem.append(enum)
+                        # Remove element from parent <require> tag
+                        # This should be a no-op in lxml.etree
+                        elem.remove(enum)
                     else:
                         self.gen.logMsg('warn', '*** NO matching group',
                             groupName, 'for enum', enum.get('name'), 'found.')
@@ -476,6 +510,28 @@
         for feature in interface.findall('remove'):
             if (matchAPIProfile(api, profile, feature)):
                 self.markRequired(feature,False)
+
+    def assignAdditionalValidity(self, interface, api, profile):
+        #
+        # Loop over all usage inside all <require> tags.
+        for feature in interface.findall('require'):
+            if (matchAPIProfile(api, profile, feature)):
+                for v in feature.findall('usage'):
+                    if v.get('command'):
+                        self.cmddict[v.get('command')].additionalValidity.append(copy.deepcopy(v))
+                    if v.get('struct'):
+                        self.typedict[v.get('struct')].additionalValidity.append(copy.deepcopy(v))
+
+        #
+        # Loop over all usage inside all <remove> tags.
+        for feature in interface.findall('remove'):
+            if (matchAPIProfile(api, profile, feature)):
+                for v in feature.findall('usage'):
+                    if v.get('command'):
+                        self.cmddict[v.get('command')].removedValidity.append(copy.deepcopy(v))
+                    if v.get('struct'):
+                        self.typedict[v.get('struct')].removedValidity.append(copy.deepcopy(v))
+
     #
     # generateFeature - generate a single type / enum group / enum / command,
     # and all its dependencies as needed.
@@ -506,7 +562,7 @@
         #   within the element.
         # For commands, there may be many in <type> tags within the element.
         # For enums, no dependencies are allowed (though perhaps if you
-        #   have a uint64 enum, it should require GLuint64).
+        #   have a uint64 enum, it should require that type).
         genProc = None
         if (ftype == 'type'):
             genProc = self.gen.genType
@@ -557,9 +613,9 @@
     #   interface - Element for <version> or <extension>
     def generateRequiredInterface(self, interface):
         """Generate required C interface for specified API version/extension"""
+
         #
         # Loop over all features inside all <require> tags.
-        # <remove> tags are ignored (handled in pass 1).
         for features in interface.findall('require'):
             for t in features.findall('type'):
                 self.generateFeature(t.get('name'), 'type', self.typedict)
@@ -567,6 +623,7 @@
                 self.generateFeature(e.get('name'), 'enum', self.enumdict)
             for c in features.findall('command'):
                 self.generateFeature(c.get('name'), 'command', self.cmddict)
+
     #
     # apiGen(genOpts) - generate interface for specified versions
     #   genOpts - GeneratorOptions object with parameters used
@@ -683,6 +740,7 @@
             self.gen.logMsg('diag', '*** PASS 1: Tagging required and removed features for',
                 f.name)
             self.requireAndRemoveFeatures(f.elem, self.genOpts.apiname, self.genOpts.profile)
+            self.assignAdditionalValidity(f.elem, self.genOpts.apiname, self.genOpts.profile)
         #
         # Pass 2: loop over specified API versions and extensions printing
         #   declarations for required things which haven't already been
diff --git a/spirv-headers_revision b/spirv-headers_revision
index 349801d..9f8dc94 100644
--- a/spirv-headers_revision
+++ b/spirv-headers_revision
@@ -1 +1 @@
-33d41376d378761ed3a4c791fc4b647761897f26
\ No newline at end of file
+e22d57b0f7d170bdcff8672eb3fb6cd5f5fd0f26
diff --git a/spirv-tools_revision b/spirv-tools_revision
index 7e3bbc1..4396e95 100644
--- a/spirv-tools_revision
+++ b/spirv-tools_revision
@@ -1 +1 @@
-923a4596b44831a07060df45caacb522613730c9
+2d89b6a9c5b88ad34784b8275141187afcc5045b
diff --git a/tests/_run_all_tests.ps1 b/tests/_run_all_tests.ps1
index 0dc014b..8c688d3 100755
--- a/tests/_run_all_tests.ps1
+++ b/tests/_run_all_tests.ps1
@@ -27,9 +27,5 @@
 }
 
 & $dPath\vk_layer_validation_tests --gtest_filter=-$TestExceptions
-if ($lastexitcode -ne 0) {
-   exit 1
-}
 
-.\vkvalidatelayerdoc.ps1
 exit $lastexitcode
diff --git a/tests/layer_validation_tests.cpp b/tests/layer_validation_tests.cpp
index 49fef96..649b052 100644
--- a/tests/layer_validation_tests.cpp
+++ b/tests/layer_validation_tests.cpp
@@ -35,6 +35,8 @@
 #include "test_common.h"
 #include "vk_layer_config.h"
 #include "vkrenderframework.h"
+#include <unordered_set>
+#include "vk_validation_error_messages.h"
 
 #define GLM_FORCE_RADIANS
 #include "glm/glm.hpp"
@@ -104,54 +106,104 @@
                                                 size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg,
                                                 void *pUserData);
 
-// ********************************************************
 // ErrorMonitor Usage:
 //
-// Call SetDesiredFailureMsg with a string to be compared against all
-// encountered log messages. Passing NULL will match all log messages.
-// logMsg will return true for skipCall only if msg is matched or NULL.
+// Call SetDesiredFailureMsg with: a string to be compared against all
+// encountered log messages, or a validation error enum identifying
+// desired error message. Passing NULL or VALIDATION_ERROR_MAX_ENUM
+// will match all log messages. logMsg will return true for skipCall
+// only if msg is matched or NULL.
 //
 // Call DesiredMsgFound to determine if the desired failure message
 // was encountered.
-
 class ErrorMonitor {
   public:
     ErrorMonitor() {
         test_platform_thread_create_mutex(&m_mutex);
         test_platform_thread_lock_mutex(&m_mutex);
-        m_msgFlags = VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
+        m_msgFlags = VK_DEBUG_REPORT_ERROR_BIT_EXT;
         m_bailout = NULL;
         test_platform_thread_unlock_mutex(&m_mutex);
     }
 
     ~ErrorMonitor() { test_platform_thread_delete_mutex(&m_mutex); }
 
+    // ErrorMonitor will look for an error message containing the specified string
     void SetDesiredFailureMsg(VkFlags msgFlags, const char *msgString) {
-        // also discard all collected messages to this point
+        // Also discard all collected messages to this point
         test_platform_thread_lock_mutex(&m_mutex);
-        m_failureMsg.clear();
+        m_failure_message_strings.clear();
+        // If we are looking for a matching string, ignore any IDs
+        m_desired_message_ids.clear();
         m_otherMsgs.clear();
-        m_desiredMsg = msgString;
+        m_desired_message_strings.insert(msgString);
         m_msgFound = VK_FALSE;
         m_msgFlags = msgFlags;
         test_platform_thread_unlock_mutex(&m_mutex);
     }
 
-    VkBool32 CheckForDesiredMsg(const char *msgString) {
+    // ErrorMonitor will look for a message ID matching the specified one
+    void SetDesiredFailureMsg(VkFlags msgFlags, UNIQUE_VALIDATION_ERROR_CODE msg_id) {
+        // Also discard all collected messages to this point
+        test_platform_thread_lock_mutex(&m_mutex);
+        m_failure_message_strings.clear();
+        // If we are looking for IDs don't look for strings
+        m_desired_message_strings.clear();
+        m_otherMsgs.clear();
+        m_desired_message_ids.insert(msg_id);
+        m_msgFound = VK_FALSE;
+        m_msgFlags = msgFlags;
+        test_platform_thread_unlock_mutex(&m_mutex);
+    }
+
+    VkBool32 CheckForDesiredMsg(uint32_t message_code, const char *msgString) {
         VkBool32 result = VK_FALSE;
         test_platform_thread_lock_mutex(&m_mutex);
         if (m_bailout != NULL) {
             *m_bailout = true;
         }
         string errorString(msgString);
-        if (errorString.find(m_desiredMsg) != string::npos) {
-            if (m_msgFound) { // If multiple matches, don't lose all but the last!
-                m_otherMsgs.push_back(m_failureMsg);
+        bool found_expected = false;
+
+        for (auto desired_msg : m_desired_message_strings) {
+            if (desired_msg.length() == 0) {
+                // An empty desired_msg string "" indicates a positive test - not expecting an error.
+                // Return true to avoid calling layers/driver with this error.
+                // And don't erase the "" string, so it remains if another error is found.
+                result = VK_TRUE;
+            } else if (errorString.find(desired_msg) != string::npos) {
+                found_expected = true;
+                m_failure_message_strings.insert(errorString);
+                m_msgFound = VK_TRUE;
+                result = VK_TRUE;
+                // We only want one match for each expected error so remove from set here
+                // Since we're about the break the loop it's ok to remove from set we're iterating over
+                m_desired_message_strings.erase(desired_msg);
+                break;
             }
-            m_failureMsg = errorString;
-            m_msgFound = VK_TRUE;
-            result = VK_TRUE;
-        } else {
+        }
+        for (auto desired_id : m_desired_message_ids) {
+            if (desired_id == VALIDATION_ERROR_MAX_ENUM) {
+                // A message ID set to MAX_ENUM indicates a positive test - not expecting an error.
+                // Return true to avoid calling layers/driver with this error.
+                result = VK_TRUE;
+            } else if (desired_id == message_code) {
+                // Double-check that the string matches the error enum
+                if (errorString.find(validation_error_map[desired_id]) != string::npos) {
+                    found_expected = true;
+                    result = VK_TRUE;
+                    m_msgFound = VK_TRUE;
+                    m_desired_message_ids.erase(desired_id);
+                    break;
+                } else {
+                    // Treat this message as a regular unexpected error, but print a warning jic
+                    printf("Message (%s) from MessageID %d does not correspond to expected message from error Database (%s)\n",
+                           errorString.c_str(), desired_id, validation_error_map[desired_id]);
+                }
+            }
+        }
+
+        if (!found_expected) {
             printf("Unexpected: %s\n", msgString);
             m_otherMsgs.push_back(errorString);
         }
@@ -161,8 +213,6 @@
 
     vector<string> GetOtherFailureMsgs(void) { return m_otherMsgs; }
 
-    string GetFailureMsg(void) { return m_failureMsg; }
-
     VkDebugReportFlagsEXT GetMessageFlags(void) { return m_msgFlags; }
 
     VkBool32 DesiredMsgFound(void) { return m_msgFound; }
@@ -187,27 +237,30 @@
     }
 
     void VerifyFound() {
-        // Not seeing the desired message is a failure. /Before/ throwing, dump
-        // any other messages.
+        // Not seeing the desired message is a failure. /Before/ throwing, dump any other messages.
         if (!DesiredMsgFound()) {
             DumpFailureMsgs();
-            FAIL() << "Did not receive expected error '" << m_desiredMsg << "'";
+            for (auto desired_msg : m_desired_message_strings) {
+                FAIL() << "Did not receive expected error '" << desired_msg << "'";
+            }
         }
     }
 
     void VerifyNotFound() {
-        // ExpectSuccess() configured us to match anything. Any error is a
-        // failure.
+        // ExpectSuccess() configured us to match anything. Any error is a failure.
         if (DesiredMsgFound()) {
             DumpFailureMsgs();
-            FAIL() << "Expected to succeed but got error: " << GetFailureMsg();
+            for (auto msg : m_failure_message_strings) {
+                FAIL() << "Expected to succeed but got error: " << msg;
+            }
         }
     }
 
   private:
     VkFlags m_msgFlags;
-    string m_desiredMsg;
-    string m_failureMsg;
+    std::unordered_set<uint32_t>m_desired_message_ids;
+    std::unordered_set<string> m_desired_message_strings;
+    std::unordered_set<string> m_failure_message_strings;
     vector<string> m_otherMsgs;
     test_platform_thread_mutex m_mutex;
     bool *m_bailout;
@@ -219,7 +272,7 @@
                                                 void *pUserData) {
     ErrorMonitor *errMonitor = (ErrorMonitor *)pUserData;
     if (msgFlags & errMonitor->GetMessageFlags()) {
-        return errMonitor->CheckForDesiredMsg(pMsg);
+        return errMonitor->CheckForDesiredMsg(msgCode, pMsg);
     }
     return false;
 }
@@ -383,7 +436,8 @@
 
     ASSERT_NO_FATAL_FAILURE(InitViewport());
 
-    VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data);
+    VkConstantBufferObj constantBuffer(m_device, bufSize * 2, sizeof(float), (const void *)&data,
+                                       VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
 
     VkShaderObj vs(m_device, vertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
     VkShaderObj ps(m_device, fragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
@@ -411,13 +465,9 @@
     // the ones we want
     if (failMask & BsoFailViewport) {
         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_VIEWPORT);
-        m_viewports.clear();
-        m_scissors.clear();
     }
     if (failMask & BsoFailScissor) {
         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_SCISSOR);
-        m_scissors.clear();
-        m_viewports.clear();
     }
     if (failMask & BsoFailBlend) {
         pipelineobj.MakeDynamic(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
@@ -515,6 +565,11 @@
     commandBuffer->BindDescriptorSet(descriptorSet);
 }
 
+class VkPositiveLayerTest : public VkLayerTest {
+  public:
+  protected:
+};
+
 class VkWsiEnabledLayerTest : public VkLayerTest {
   public:
   protected:
@@ -866,11 +921,9 @@
     ASSERT_NO_FATAL_FAILURE(InitState());
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "value of pCreateInfo->pNext must be NULL");
-    // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be
-    // NULL.
+    // Set VkMemoryAllocateInfo::pNext to a non-NULL value, when pNext must be NULL.
     // Need to pick a function that has no allowed pNext structure types.
-    // Expected to trigger an error with
-    // parameter_validation::validate_struct_pnext
+    // Expected to trigger an error with parameter_validation::validate_struct_pnext
     VkEvent event = VK_NULL_HANDLE;
     VkEventCreateInfo event_alloc_info = {};
     // Zero-initialization will provide the correct sType
@@ -885,86 +938,13 @@
     // Set VkMemoryAllocateInfo::pNext to a non-NULL value, but use
     // a function that has allowed pNext structure types and specify
     // a structure type that is not allowed.
-    // Expected to trigger an error with
-    // parameter_validation::validate_struct_pnext
+    // Expected to trigger an error with parameter_validation::validate_struct_pnext
     VkDeviceMemory memory = VK_NULL_HANDLE;
     VkMemoryAllocateInfo memory_alloc_info = {};
     memory_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     memory_alloc_info.pNext = &app_info;
     vkAllocateMemory(device(), &memory_alloc_info, NULL, &memory);
     m_errorMonitor->VerifyFound();
-
-    // Positive test to check parameter_validation and unique_objects support
-    // for NV_dedicated_allocation
-    uint32_t extension_count = 0;
-    bool supports_nv_dedicated_allocation = false;
-    VkResult err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, nullptr);
-    ASSERT_VK_SUCCESS(err);
-
-    if (extension_count > 0) {
-        std::vector<VkExtensionProperties> available_extensions(extension_count);
-
-        err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]);
-        ASSERT_VK_SUCCESS(err);
-
-        for (const auto &extension_props : available_extensions) {
-            if (strcmp(extension_props.extensionName, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
-                supports_nv_dedicated_allocation = true;
-            }
-        }
-    }
-
-    if (supports_nv_dedicated_allocation) {
-        m_errorMonitor->ExpectSuccess();
-
-        VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
-        dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
-        dedicated_buffer_create_info.pNext = nullptr;
-        dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
-
-        uint32_t queue_family_index = 0;
-        VkBufferCreateInfo buffer_create_info = {};
-        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-        buffer_create_info.pNext = &dedicated_buffer_create_info;
-        buffer_create_info.size = 1024;
-        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
-        buffer_create_info.queueFamilyIndexCount = 1;
-        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
-
-        VkBuffer buffer;
-        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
-        ASSERT_VK_SUCCESS(err);
-
-        VkMemoryRequirements memory_reqs;
-        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
-
-        VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
-        dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
-        dedicated_memory_info.pNext = nullptr;
-        dedicated_memory_info.buffer = buffer;
-        dedicated_memory_info.image = VK_NULL_HANDLE;
-
-        VkMemoryAllocateInfo memory_info = {};
-        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-        memory_info.pNext = &dedicated_memory_info;
-        memory_info.allocationSize = memory_reqs.size;
-
-        bool pass;
-        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
-        ASSERT_TRUE(pass);
-
-        VkDeviceMemory buffer_memory;
-        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
-        ASSERT_VK_SUCCESS(err);
-
-        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
-        ASSERT_VK_SUCCESS(err);
-
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        vkFreeMemory(m_device->device(), buffer_memory, NULL);
-
-        m_errorMonitor->VerifyNotFound();
-    }
 }
 
 TEST_F(VkLayerTest, UnrecognizedValue) {
@@ -1128,371 +1108,6 @@
     EndCommandBuffer();
 }
 
-// This is a positive test. No failures are expected.
-TEST_F(VkLayerTest, IgnoreUnrelatedDescriptor) {
-    TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSet validation code "
-                     "is ignoring VkWriteDescriptorSet members that are not "
-                     "related to the descriptor type specified by "
-                     "VkWriteDescriptorSet::descriptorType.  Correct "
-                     "validation behavior will result in the test running to "
-                     "completion without validation errors.");
-
-    const uintptr_t invalid_ptr = 0xcdcdcdcd;
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    // Image Case
-    {
-        m_errorMonitor->ExpectSuccess();
-
-        VkImage image;
-        const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
-        const int32_t tex_width = 32;
-        const int32_t tex_height = 32;
-        VkImageCreateInfo image_create_info = {};
-        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
-        image_create_info.pNext = NULL;
-        image_create_info.imageType = VK_IMAGE_TYPE_2D;
-        image_create_info.format = tex_format;
-        image_create_info.extent.width = tex_width;
-        image_create_info.extent.height = tex_height;
-        image_create_info.extent.depth = 1;
-        image_create_info.mipLevels = 1;
-        image_create_info.arrayLayers = 1;
-        image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
-        image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
-        image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
-        image_create_info.flags = 0;
-        VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
-        ASSERT_VK_SUCCESS(err);
-
-        VkMemoryRequirements memory_reqs;
-        VkDeviceMemory image_memory;
-        bool pass;
-        VkMemoryAllocateInfo memory_info = {};
-        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-        memory_info.pNext = NULL;
-        memory_info.allocationSize = 0;
-        memory_info.memoryTypeIndex = 0;
-        vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
-        memory_info.allocationSize = memory_reqs.size;
-        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
-        ASSERT_TRUE(pass);
-        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
-        ASSERT_VK_SUCCESS(err);
-        err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
-        ASSERT_VK_SUCCESS(err);
-
-        VkImageViewCreateInfo image_view_create_info = {};
-        image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
-        image_view_create_info.image = image;
-        image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
-        image_view_create_info.format = tex_format;
-        image_view_create_info.subresourceRange.layerCount = 1;
-        image_view_create_info.subresourceRange.baseMipLevel = 0;
-        image_view_create_info.subresourceRange.levelCount = 1;
-        image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-
-        VkImageView view;
-        err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorPoolSize ds_type_count = {};
-        ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
-        ds_type_count.descriptorCount = 1;
-
-        VkDescriptorPoolCreateInfo ds_pool_ci = {};
-        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
-        ds_pool_ci.pNext = NULL;
-        ds_pool_ci.maxSets = 1;
-        ds_pool_ci.poolSizeCount = 1;
-        ds_pool_ci.pPoolSizes = &ds_type_count;
-
-        VkDescriptorPool ds_pool;
-        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSetLayoutBinding dsl_binding = {};
-        dsl_binding.binding = 0;
-        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
-        dsl_binding.descriptorCount = 1;
-        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
-        dsl_binding.pImmutableSamplers = NULL;
-
-        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
-        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
-        ds_layout_ci.pNext = NULL;
-        ds_layout_ci.bindingCount = 1;
-        ds_layout_ci.pBindings = &dsl_binding;
-        VkDescriptorSetLayout ds_layout;
-        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSet descriptor_set;
-        VkDescriptorSetAllocateInfo alloc_info = {};
-        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
-        alloc_info.descriptorSetCount = 1;
-        alloc_info.descriptorPool = ds_pool;
-        alloc_info.pSetLayouts = &ds_layout;
-        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorImageInfo image_info = {};
-        image_info.imageView = view;
-        image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-
-        VkWriteDescriptorSet descriptor_write;
-        memset(&descriptor_write, 0, sizeof(descriptor_write));
-        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-        descriptor_write.dstSet = descriptor_set;
-        descriptor_write.dstBinding = 0;
-        descriptor_write.descriptorCount = 1;
-        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
-        descriptor_write.pImageInfo = &image_info;
-
-        // Set pBufferInfo and pTexelBufferView to invalid values, which should
-        // be
-        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
-        // This will most likely produce a crash if the parameter_validation
-        // layer
-        // does not correctly ignore pBufferInfo.
-        descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
-        descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
-
-        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
-
-        m_errorMonitor->VerifyNotFound();
-
-        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
-        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
-        vkDestroyImageView(m_device->device(), view, NULL);
-        vkDestroyImage(m_device->device(), image, NULL);
-        vkFreeMemory(m_device->device(), image_memory, NULL);
-    }
-
-    // Buffer Case
-    {
-        m_errorMonitor->ExpectSuccess();
-
-        VkBuffer buffer;
-        uint32_t queue_family_index = 0;
-        VkBufferCreateInfo buffer_create_info = {};
-        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-        buffer_create_info.size = 1024;
-        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
-        buffer_create_info.queueFamilyIndexCount = 1;
-        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
-
-        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
-        ASSERT_VK_SUCCESS(err);
-
-        VkMemoryRequirements memory_reqs;
-        VkDeviceMemory buffer_memory;
-        bool pass;
-        VkMemoryAllocateInfo memory_info = {};
-        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-        memory_info.pNext = NULL;
-        memory_info.allocationSize = 0;
-        memory_info.memoryTypeIndex = 0;
-
-        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
-        memory_info.allocationSize = memory_reqs.size;
-        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
-        ASSERT_TRUE(pass);
-
-        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
-        ASSERT_VK_SUCCESS(err);
-        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorPoolSize ds_type_count = {};
-        ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-        ds_type_count.descriptorCount = 1;
-
-        VkDescriptorPoolCreateInfo ds_pool_ci = {};
-        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
-        ds_pool_ci.pNext = NULL;
-        ds_pool_ci.maxSets = 1;
-        ds_pool_ci.poolSizeCount = 1;
-        ds_pool_ci.pPoolSizes = &ds_type_count;
-
-        VkDescriptorPool ds_pool;
-        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSetLayoutBinding dsl_binding = {};
-        dsl_binding.binding = 0;
-        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-        dsl_binding.descriptorCount = 1;
-        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
-        dsl_binding.pImmutableSamplers = NULL;
-
-        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
-        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
-        ds_layout_ci.pNext = NULL;
-        ds_layout_ci.bindingCount = 1;
-        ds_layout_ci.pBindings = &dsl_binding;
-        VkDescriptorSetLayout ds_layout;
-        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSet descriptor_set;
-        VkDescriptorSetAllocateInfo alloc_info = {};
-        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
-        alloc_info.descriptorSetCount = 1;
-        alloc_info.descriptorPool = ds_pool;
-        alloc_info.pSetLayouts = &ds_layout;
-        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorBufferInfo buffer_info = {};
-        buffer_info.buffer = buffer;
-        buffer_info.offset = 0;
-        buffer_info.range = 1024;
-
-        VkWriteDescriptorSet descriptor_write;
-        memset(&descriptor_write, 0, sizeof(descriptor_write));
-        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-        descriptor_write.dstSet = descriptor_set;
-        descriptor_write.dstBinding = 0;
-        descriptor_write.descriptorCount = 1;
-        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
-        descriptor_write.pBufferInfo = &buffer_info;
-
-        // Set pImageInfo and pTexelBufferView to invalid values, which should
-        // be
-        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
-        // This will most likely produce a crash if the parameter_validation
-        // layer
-        // does not correctly ignore pImageInfo.
-        descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
-        descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
-
-        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
-
-        m_errorMonitor->VerifyNotFound();
-
-        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
-        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
-        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        vkFreeMemory(m_device->device(), buffer_memory, NULL);
-    }
-
-    // Texel Buffer Case
-    {
-        m_errorMonitor->ExpectSuccess();
-
-        VkBuffer buffer;
-        uint32_t queue_family_index = 0;
-        VkBufferCreateInfo buffer_create_info = {};
-        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-        buffer_create_info.size = 1024;
-        buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
-        buffer_create_info.queueFamilyIndexCount = 1;
-        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
-
-        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
-        ASSERT_VK_SUCCESS(err);
-
-        VkMemoryRequirements memory_reqs;
-        VkDeviceMemory buffer_memory;
-        bool pass;
-        VkMemoryAllocateInfo memory_info = {};
-        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-        memory_info.pNext = NULL;
-        memory_info.allocationSize = 0;
-        memory_info.memoryTypeIndex = 0;
-
-        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
-        memory_info.allocationSize = memory_reqs.size;
-        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
-        ASSERT_TRUE(pass);
-
-        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
-        ASSERT_VK_SUCCESS(err);
-        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
-        ASSERT_VK_SUCCESS(err);
-
-        VkBufferViewCreateInfo buff_view_ci = {};
-        buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
-        buff_view_ci.buffer = buffer;
-        buff_view_ci.format = VK_FORMAT_R8_UNORM;
-        buff_view_ci.range = VK_WHOLE_SIZE;
-        VkBufferView buffer_view;
-        err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
-
-        VkDescriptorPoolSize ds_type_count = {};
-        ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
-        ds_type_count.descriptorCount = 1;
-
-        VkDescriptorPoolCreateInfo ds_pool_ci = {};
-        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
-        ds_pool_ci.pNext = NULL;
-        ds_pool_ci.maxSets = 1;
-        ds_pool_ci.poolSizeCount = 1;
-        ds_pool_ci.pPoolSizes = &ds_type_count;
-
-        VkDescriptorPool ds_pool;
-        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSetLayoutBinding dsl_binding = {};
-        dsl_binding.binding = 0;
-        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
-        dsl_binding.descriptorCount = 1;
-        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
-        dsl_binding.pImmutableSamplers = NULL;
-
-        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
-        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
-        ds_layout_ci.pNext = NULL;
-        ds_layout_ci.bindingCount = 1;
-        ds_layout_ci.pBindings = &dsl_binding;
-        VkDescriptorSetLayout ds_layout;
-        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
-        ASSERT_VK_SUCCESS(err);
-
-        VkDescriptorSet descriptor_set;
-        VkDescriptorSetAllocateInfo alloc_info = {};
-        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
-        alloc_info.descriptorSetCount = 1;
-        alloc_info.descriptorPool = ds_pool;
-        alloc_info.pSetLayouts = &ds_layout;
-        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
-        ASSERT_VK_SUCCESS(err);
-
-        VkWriteDescriptorSet descriptor_write;
-        memset(&descriptor_write, 0, sizeof(descriptor_write));
-        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
-        descriptor_write.dstSet = descriptor_set;
-        descriptor_write.dstBinding = 0;
-        descriptor_write.descriptorCount = 1;
-        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
-        descriptor_write.pTexelBufferView = &buffer_view;
-
-        // Set pImageInfo and pBufferInfo to invalid values, which should be
-        //  ignored for descriptorType ==
-        //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
-        // This will most likely produce a crash if the parameter_validation
-        // layer
-        // does not correctly ignore pImageInfo and pBufferInfo.
-        descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
-        descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
-
-        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
-
-        m_errorMonitor->VerifyNotFound();
-
-        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
-        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
-        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
-        vkDestroyBufferView(m_device->device(), buffer_view, NULL);
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        vkFreeMemory(m_device->device(), buffer_memory, NULL);
-    }
-}
-
 TEST_F(VkLayerTest, PSOPolygonModeInvalid) {
     VkResult err;
 
@@ -1559,20 +1174,6 @@
     }
     m_errorMonitor->VerifyFound();
 
-    // Try again with polygonMode=FILL. No error is expected
-    m_errorMonitor->ExpectSuccess();
-    {
-        VkPipelineObj pipe(&test_device);
-        pipe.AddShader(&vs);
-        pipe.AddShader(&fs);
-        pipe.AddColorAttachment();
-        // Set polygonMode to a good value
-        rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
-        pipe.SetRasterization(&rs_ci);
-        pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
-    }
-    m_errorMonitor->VerifyNotFound();
-
     vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL);
 }
 
@@ -1588,7 +1189,7 @@
     fenceInfo.pNext = NULL;
     fenceInfo.flags = 0;
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting CB");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Resetting command buffer");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -1632,7 +1233,7 @@
     fenceInfo.pNext = NULL;
     fenceInfo.flags = 0;
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active CB");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Calling vkBeginCommandBuffer() on active command buffer");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitViewport());
@@ -1678,124 +1279,6 @@
 }
 #endif
 
-// This is a positive test. No failures are expected.
-TEST_F(VkLayerTest, TestAliasedMemoryTracking) {
-    VkResult err;
-    bool pass;
-
-    TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
-                     "the buffer, create an image, and bind the same memory to "
-                     "it");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkBuffer buffer;
-    VkImage image;
-    VkDeviceMemory mem;
-    VkMemoryRequirements mem_reqs;
-
-    VkBufferCreateInfo buf_info = {};
-    buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buf_info.pNext = NULL;
-    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
-    buf_info.size = 256;
-    buf_info.queueFamilyIndexCount = 0;
-    buf_info.pQueueFamilyIndices = NULL;
-    buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-    buf_info.flags = 0;
-    err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
-    ASSERT_VK_SUCCESS(err);
-
-    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
-
-    VkMemoryAllocateInfo alloc_info = {};
-    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    alloc_info.pNext = NULL;
-    alloc_info.memoryTypeIndex = 0;
-
-    // Ensure memory is big enough for both bindings
-    alloc_info.allocationSize = 0x10000;
-
-    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
-    if (!pass) {
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        return;
-    }
-
-    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
-    ASSERT_VK_SUCCESS(err);
-
-    uint8_t *pData;
-    err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
-    ASSERT_VK_SUCCESS(err);
-
-    memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
-
-    vkUnmapMemory(m_device->device(), mem);
-
-    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
-    ASSERT_VK_SUCCESS(err);
-
-    // NOW, destroy the buffer. Obviously, the resource no longer occupies this
-    // memory. In fact, it was never used by the GPU.
-    // Just be be sure, wait for idle.
-    vkDestroyBuffer(m_device->device(), buffer, NULL);
-    vkDeviceWaitIdle(m_device->device());
-
-    VkImageCreateInfo image_create_info = {};
-    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
-    image_create_info.pNext = NULL;
-    image_create_info.imageType = VK_IMAGE_TYPE_2D;
-    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
-    image_create_info.extent.width = 64;
-    image_create_info.extent.height = 64;
-    image_create_info.extent.depth = 1;
-    image_create_info.mipLevels = 1;
-    image_create_info.arrayLayers = 1;
-    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
-    image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
-    image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
-    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
-    image_create_info.queueFamilyIndexCount = 0;
-    image_create_info.pQueueFamilyIndices = NULL;
-    image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-    image_create_info.flags = 0;
-
-    VkMemoryAllocateInfo mem_alloc = {};
-    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    mem_alloc.pNext = NULL;
-    mem_alloc.allocationSize = 0;
-    mem_alloc.memoryTypeIndex = 0;
-
-    /* Create a mappable image.  It will be the texture if linear images are ok
-    * to be textures or it will be the staging image if they are not.
-    */
-    err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
-    ASSERT_VK_SUCCESS(err);
-
-    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
-
-    mem_alloc.allocationSize = mem_reqs.size;
-
-    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
-    if (!pass) {
-        vkDestroyImage(m_device->device(), image, NULL);
-        return;
-    }
-
-    // VALIDATION FAILURE:
-    err = vkBindImageMemory(m_device->device(), image, mem, 0);
-    ASSERT_VK_SUCCESS(err);
-
-    m_errorMonitor->VerifyNotFound();
-
-    vkFreeMemory(m_device->device(), mem, NULL);
-    vkDestroyBuffer(m_device->device(), buffer, NULL);
-    vkDestroyImage(m_device->device(), image, NULL);
-}
-
 TEST_F(VkLayerTest, InvalidMemoryAliasing) {
     TEST_DESCRIPTION("Create a buffer and image, allocate memory, and bind the "
                      "buffer and image to memory such that they will alias.");
@@ -1805,6 +1288,7 @@
 
     VkBuffer buffer, buffer2;
     VkImage image;
+    VkImage image2;
     VkDeviceMemory mem;     // buffer will be bound first
     VkDeviceMemory mem_img; // image bound first
     VkMemoryRequirements buff_mem_reqs, img_mem_reqs;
@@ -1845,6 +1329,8 @@
 
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
     ASSERT_VK_SUCCESS(err);
+    err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image2);
+    ASSERT_VK_SUCCESS(err);
 
     vkGetImageMemoryRequirements(m_device->device(), image, &img_mem_reqs);
 
@@ -1871,13 +1357,13 @@
     err = vkBindImageMemory(m_device->device(), image, mem, 0);
     m_errorMonitor->VerifyFound();
 
-    // Now correctly bind image to second mem allocation before incorrectly
+    // Now correctly bind image2 to second mem allocation before incorrectly
     // aliasing buffer2
     err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer2);
     ASSERT_VK_SUCCESS(err);
     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem_img);
     ASSERT_VK_SUCCESS(err);
-    err = vkBindImageMemory(m_device->device(), image, mem_img, 0);
+    err = vkBindImageMemory(m_device->device(), image2, mem_img, 0);
     ASSERT_VK_SUCCESS(err);
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "is aliased with non-linear image 0x");
     err = vkBindBufferMemory(m_device->device(), buffer2, mem_img, 0);
@@ -1886,6 +1372,7 @@
     vkDestroyBuffer(m_device->device(), buffer, NULL);
     vkDestroyBuffer(m_device->device(), buffer2, NULL);
     vkDestroyImage(m_device->device(), image, NULL);
+    vkDestroyImage(m_device->device(), image2, NULL);
     vkFreeMemory(m_device->device(), mem, NULL);
     vkFreeMemory(m_device->device(), mem_img, NULL);
 }
@@ -1991,99 +1478,6 @@
     vkFreeMemory(m_device->device(), mem, NULL);
 }
 
-TEST_F(VkLayerTest, NonCoherentMemoryMapping) {
-
-    TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory "
-                     "mapping while using VK_WHOLE_SIZE does not cause access "
-                     "violations");
-    VkResult err;
-    uint8_t *pData;
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkDeviceMemory mem;
-    VkMemoryRequirements mem_reqs;
-    mem_reqs.memoryTypeBits = 0xFFFFFFFF;
-    VkMemoryAllocateInfo alloc_info = {};
-    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    alloc_info.pNext = NULL;
-    alloc_info.memoryTypeIndex = 0;
-
-    static const VkDeviceSize allocation_size = 0x1000;
-    alloc_info.allocationSize = allocation_size;
-
-    // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
-    bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
-                                                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-    if (!pass) {
-        pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
-                                               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
-                                               VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-        if (!pass) {
-            pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
-                                                   VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
-                                                       VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
-                                                   VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-            if (!pass) {
-                return;
-            }
-        }
-    }
-
-    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
-    ASSERT_VK_SUCCESS(err);
-
-    // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire
-    // mapped range
-    m_errorMonitor->ExpectSuccess();
-    err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
-    ASSERT_VK_SUCCESS(err);
-    VkMappedMemoryRange mmr = {};
-    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
-    mmr.memory = mem;
-    mmr.offset = 0;
-    mmr.size = VK_WHOLE_SIZE;
-    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    m_errorMonitor->VerifyNotFound();
-    vkUnmapMemory(m_device->device(), mem);
-
-    // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire
-    // mapped range
-    m_errorMonitor->ExpectSuccess();
-    err = vkMapMemory(m_device->device(), mem, 13, VK_WHOLE_SIZE, 0, (void **)&pData);
-    ASSERT_VK_SUCCESS(err);
-    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
-    mmr.memory = mem;
-    mmr.offset = 13;
-    mmr.size = VK_WHOLE_SIZE;
-    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    m_errorMonitor->VerifyNotFound();
-    vkUnmapMemory(m_device->device(), mem);
-
-    // Map with prime offset and size
-    // Flush/Invalidate subrange of mapped area with prime offset and size
-    m_errorMonitor->ExpectSuccess();
-    err = vkMapMemory(m_device->device(), mem, allocation_size - 137, 109, 0, (void **)&pData);
-    ASSERT_VK_SUCCESS(err);
-    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
-    mmr.memory = mem;
-    mmr.offset = allocation_size - 107;
-    mmr.size = 61;
-    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
-    ASSERT_VK_SUCCESS(err);
-    m_errorMonitor->VerifyNotFound();
-    vkUnmapMemory(m_device->device(), mem);
-
-    vkFreeMemory(m_device->device(), mem, NULL);
-}
-
 TEST_F(VkLayerTest, EnableWsiBeforeUse) {
     VkResult err;
     bool pass;
@@ -2286,13 +1680,20 @@
     ASSERT_TRUE(pass);
     m_errorMonitor->VerifyFound();
 
+    // Add a fence to avoid (justifiable) error about not providing fence OR semaphore
+    VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+    VkFence fence;
+    err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
+
     // Try to acquire an image:
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "extension was not enabled for this");
-    err = vkAcquireNextImageKHR(m_device->device(), swapchain, 0, VK_NULL_HANDLE, VK_NULL_HANDLE, &image_index);
+    err = vkAcquireNextImageKHR(m_device->device(), swapchain, 0, VK_NULL_HANDLE, fence, &image_index);
     pass = (err != VK_SUCCESS);
     ASSERT_TRUE(pass);
     m_errorMonitor->VerifyFound();
 
+    vkDestroyFence(m_device->device(), fence, nullptr);
+
     // Try to present an image:
     //
     // NOTE: Currently can't test this because a real swapchain is needed (as
@@ -2305,336 +1706,6 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) {
-
-#if defined(VK_USE_PLATFORM_XCB_KHR)
-    VkSurfaceKHR surface = VK_NULL_HANDLE;
-
-    VkResult err;
-    bool pass;
-    VkSwapchainKHR swapchain = VK_NULL_HANDLE;
-    VkSwapchainCreateInfoKHR swapchain_create_info = {};
-    //    uint32_t swapchain_image_count = 0;
-    //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
-    //    uint32_t image_index = 0;
-    //    VkPresentInfoKHR present_info = {};
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    // Use the create function from one of the VK_KHR_*_surface extension in
-    // order to create a surface, testing all known errors in the process,
-    // before successfully creating a surface:
-    // First, try to create a surface without a VkXcbSurfaceCreateInfoKHR:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo specified as NULL");
-    err = vkCreateXcbSurfaceKHR(instance(), NULL, NULL, &surface);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, try to create a surface with the wrong
-    // VkXcbSurfaceCreateInfoKHR::sType:
-    VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
-    xcb_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
-    err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Create a native window, and then correctly create a surface:
-    xcb_connection_t *connection;
-    xcb_screen_t *screen;
-    xcb_window_t xcb_window;
-    xcb_intern_atom_reply_t *atom_wm_delete_window;
-
-    const xcb_setup_t *setup;
-    xcb_screen_iterator_t iter;
-    int scr;
-    uint32_t value_mask, value_list[32];
-    int width = 1;
-    int height = 1;
-
-    connection = xcb_connect(NULL, &scr);
-    ASSERT_TRUE(connection != NULL);
-    setup = xcb_get_setup(connection);
-    iter = xcb_setup_roots_iterator(setup);
-    while (scr-- > 0)
-        xcb_screen_next(&iter);
-    screen = iter.data;
-
-    xcb_window = xcb_generate_id(connection);
-
-    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
-    value_list[0] = screen->black_pixel;
-    value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
-
-    xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0,
-                      XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list);
-
-    /* Magic code that will send notification when window is destroyed */
-    xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
-    xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0);
-
-    xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
-    atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
-    xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom);
-    free(reply);
-
-    xcb_map_window(connection, xcb_window);
-
-    // Force the x/y coordinates to 100,100 results are identical in consecutive
-    // runs
-    const uint32_t coords[] = {100, 100};
-    xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
-
-    // Finally, try to correctly create a surface:
-    xcb_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
-    xcb_create_info.pNext = NULL;
-    xcb_create_info.flags = 0;
-    xcb_create_info.connection = connection;
-    xcb_create_info.window = xcb_window;
-    err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Check if surface supports presentation:
-
-    // 1st, do so without having queried the queue families:
-    VkBool32 supported = false;
-    // TODO: Get the following error to come out:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "called before calling the vkGetPhysicalDeviceQueueFamilyProperties "
-                                         "function");
-    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
-    pass = (err != VK_SUCCESS);
-    //    ASSERT_TRUE(pass);
-    //    m_errorMonitor->VerifyFound();
-
-    // Next, query a queue family index that's too large:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
-    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 100000, surface, &supported);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Finally, do so correctly:
-    // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
-    // SUPPORTED
-    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Before proceeding, try to create a swapchain without having called
-    // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
-    swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
-    swapchain_create_info.pNext = NULL;
-    swapchain_create_info.flags = 0;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Get the surface capabilities:
-    VkSurfaceCapabilitiesKHR surface_capabilities;
-
-    // Do so correctly (only error logged by this entrypoint is if the
-    // extension isn't enabled):
-    err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Get the surface formats:
-    uint32_t surface_format_count;
-
-    // First, try without a pointer to surface_format_count:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
-                                                                        "specified as NULL");
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call with a non-NULL pSurfaceFormats, even though we haven't
-    // correctly done a 1st try (to get the count):
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
-    surface_format_count = 0;
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Allocate memory for the correct number of VkSurfaceFormatKHR's:
-    VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
-
-    // Next, do a 2nd try with surface_format_count being set too high:
-    surface_format_count += 5;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Finally, do a correct 1st and 2nd try:
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Get the surface present modes:
-    uint32_t surface_present_mode_count;
-
-    // First, try without a pointer to surface_format_count:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
-                                                                        "specified as NULL");
-
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
-    // correctly done a 1st try (to get the count):
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
-    surface_present_mode_count = 0;
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
-                                              (VkPresentModeKHR *)&surface_present_mode_count);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Allocate memory for the correct number of VkSurfaceFormatKHR's:
-    VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
-
-    // Next, do a 2nd try with surface_format_count being set too high:
-    surface_present_mode_count += 5;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Finally, do a correct 1st and 2nd try:
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
-    pass = (err == VK_SUCCESS);
-    ASSERT_TRUE(pass);
-
-    // Create a swapchain:
-
-    // First, try without a pointer to swapchain_create_info:
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
-                                                                        "specified as NULL");
-
-    err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call with a non-NULL swapchain_create_info, that has the wrong
-    // sType:
-    swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
-
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call with a NULL swapchain pointer:
-    swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
-    swapchain_create_info.pNext = NULL;
-    swapchain_create_info.flags = 0;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
-                                                                        "specified as NULL");
-
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // TODO: Enhance swapchain layer so that
-    // swapchain_create_info.queueFamilyIndexCount is checked against something?
-
-    // Next, call with a queue family index that's too large:
-    uint32_t queueFamilyIndex[2] = {100000, 0};
-    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
-    swapchain_create_info.queueFamilyIndexCount = 2;
-    swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
-    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
-    swapchain_create_info.queueFamilyIndexCount = 1;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
-                                         "pCreateInfo->pQueueFamilyIndices).");
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-
-    // Next, call with an invalid imageSharingMode:
-    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
-    swapchain_create_info.queueFamilyIndexCount = 1;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
-    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
-    pass = (err != VK_SUCCESS);
-    ASSERT_TRUE(pass);
-    m_errorMonitor->VerifyFound();
-    // Fix for the future:
-    // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
-    // SUPPORTED
-    swapchain_create_info.queueFamilyIndexCount = 0;
-    queueFamilyIndex[0] = 0;
-    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
-    // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
-    // Get the images from a swapchain:
-    // Acquire an image from a swapchain:
-    // Present an image to a swapchain:
-    // Destroy the swapchain:
-
-    // TODOs:
-    //
-    // - Try destroying the device without first destroying the swapchain
-    //
-    // - Try destroying the device without first destroying the surface
-    //
-    // - Try destroying the surface without first destroying the swapchain
-
-    // Destroy the surface:
-    vkDestroySurfaceKHR(instance(), surface, NULL);
-
-    // Tear down the window:
-    xcb_destroy_window(connection, xcb_window);
-    xcb_disconnect(connection);
-
-#else  // VK_USE_PLATFORM_XCB_KHR
-    return;
-#endif // VK_USE_PLATFORM_XCB_KHR
-}
-
 TEST_F(VkLayerTest, MapMemWithoutHostVisibleBit) {
     VkResult err;
     bool pass;
@@ -2667,14 +1738,12 @@
     image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
     image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
     image_create_info.flags = 0;
+    image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
 
     VkMemoryAllocateInfo mem_alloc = {};
     mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
     mem_alloc.pNext = NULL;
     mem_alloc.allocationSize = 0;
-    // Introduce failure, do NOT set memProps to
-    // VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
-    mem_alloc.memoryTypeIndex = 1;
 
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
     ASSERT_VK_SUCCESS(err);
@@ -2817,142 +1886,6 @@
 
     m_errorMonitor->VerifyFound();
 }
-// This is a positive test. We used to expect error in this case but spec now
-// allows it
-TEST_F(VkLayerTest, ResetUnsignaledFence) {
-    m_errorMonitor->ExpectSuccess();
-    vk_testing::Fence testFence;
-    VkFenceCreateInfo fenceInfo = {};
-    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fenceInfo.pNext = NULL;
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    testFence.init(*m_device, fenceInfo);
-    VkFence fences[1] = {testFence.handle()};
-    VkResult result = vkResetFences(m_device->device(), 1, fences);
-    ASSERT_VK_SUCCESS(result);
-
-    m_errorMonitor->VerifyNotFound();
-}
-#if 0 // A few devices have issues with this test so disabling for now
-TEST_F(VkLayerTest, LongFenceChain)
-{
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkResult err;
-
-    std::vector<VkFence> fences;
-
-    const int chainLength = 32768;
-
-    for (int i = 0; i < chainLength; i++) {
-        VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
-        VkFence fence;
-        err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
-        ASSERT_VK_SUCCESS(err);
-
-        fences.push_back(fence);
-
-        VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
-            0, nullptr, 0, nullptr };
-        err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
-        ASSERT_VK_SUCCESS(err);
-
-    }
-
-    // BOOM, stack overflow.
-    vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
-
-    for (auto fence : fences)
-        vkDestroyFence(m_device->device(), fence, nullptr);
-
-    m_errorMonitor->VerifyNotFound();
-}
-#endif
-TEST_F(VkLayerTest, CommandBufferSimultaneousUseSync) {
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkResult err;
-
-    // Record (empty!) command buffer that can be submitted multiple times
-    // simultaneously.
-    VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
-                                     VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr};
-    m_commandBuffer->BeginCommandBuffer(&cbbi);
-    m_commandBuffer->EndCommandBuffer();
-
-    VkFenceCreateInfo fci = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
-    VkFence fence;
-    err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
-    ASSERT_VK_SUCCESS(err);
-
-    VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
-    VkSemaphore s1, s2;
-    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
-    ASSERT_VK_SUCCESS(err);
-    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
-    ASSERT_VK_SUCCESS(err);
-
-    // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
-    VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1};
-    err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
-    ASSERT_VK_SUCCESS(err);
-
-    // Submit CB again, signaling s2.
-    si.pSignalSemaphores = &s2;
-    err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
-    ASSERT_VK_SUCCESS(err);
-
-    // Wait for fence.
-    err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-    ASSERT_VK_SUCCESS(err);
-
-    // CB is still in flight from second submission, but semaphore s1 is no
-    // longer in flight. delete it.
-    vkDestroySemaphore(m_device->device(), s1, nullptr);
-
-    m_errorMonitor->VerifyNotFound();
-
-    // Force device idle and clean up remaining objects
-    vkDeviceWaitIdle(m_device->device());
-    vkDestroySemaphore(m_device->device(), s2, nullptr);
-    vkDestroyFence(m_device->device(), fence, nullptr);
-}
-
-TEST_F(VkLayerTest, FenceCreateSignaledWaitHandling) {
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkResult err;
-
-    // A fence created signaled
-    VkFenceCreateInfo fci1 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT};
-    VkFence f1;
-    err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
-    ASSERT_VK_SUCCESS(err);
-
-    // A fence created not
-    VkFenceCreateInfo fci2 = {VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0};
-    VkFence f2;
-    err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
-    ASSERT_VK_SUCCESS(err);
-
-    // Submit the unsignaled fence
-    VkSubmitInfo si = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr};
-    err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
-
-    // Wait on both fences, with signaled first.
-    VkFence fences[] = {f1, f2};
-    vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
-
-    // Should have both retired!
-    vkDestroyFence(m_device->device(), f1, nullptr);
-    vkDestroyFence(m_device->device(), f2, nullptr);
-
-    m_errorMonitor->VerifyNotFound();
-}
 
 TEST_F(VkLayerTest, InvalidUsageBits) {
     TEST_DESCRIPTION("Specify wrong usage for image then create conflicting view of image "
@@ -2995,46 +1928,20 @@
     region.imageExtent.width = 16;
     region.imageExtent.depth = 1;
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for buffer ");
     // Buffer usage not set to TRANSFER_SRC and image usage not set to
     // TRANSFER_DST
     BeginCommandBuffer();
-    vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
-                           VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
-    m_errorMonitor->VerifyFound();
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid usage flag for image ");
+    // two separate errors from this call:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "image should have VK_IMAGE_USAGE_TRANSFER_DST_BIT");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "buffer should have VK_BUFFER_USAGE_TRANSFER_SRC_BIT");
+
     vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer.handle(), image.handle(),
                            VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, ValidUsage) {
-    TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
-                     "doesn't generate validation errors");
 
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    m_errorMonitor->ExpectSuccess();
-    // Verify that we can create a view with usage INPUT_ATTACHMENT
-    VkImageObj image(m_device);
-    image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-    VkImageView imageView;
-    VkImageViewCreateInfo ivci = {};
-    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
-    ivci.image = image.handle();
-    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
-    ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
-    ivci.subresourceRange.layerCount = 1;
-    ivci.subresourceRange.baseMipLevel = 0;
-    ivci.subresourceRange.levelCount = 1;
-    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-
-    vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
-    m_errorMonitor->VerifyNotFound();
-    vkDestroyImageView(m_device->device(), imageView, NULL);
-}
 #endif // MEM_TRACKER_TESTS
 
 #if OBJ_TRACKER_TESTS
@@ -3620,6 +2527,53 @@
     }
 }
 
+TEST_F(VkLayerTest, BlitImageFormats) {
+
+    // Image blit with mismatched formats
+    const char * expected_message =
+        "vkCmdBlitImage: If one of srcImage and dstImage images has signed/unsigned integer format,"
+        " the other one must also have signed/unsigned integer format";
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImageObj src_image(m_device);
+    src_image.init(64, 64, VK_FORMAT_A2B10G10R10_UINT_PACK32, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0);
+    VkImageObj dst_image(m_device);
+    dst_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0);
+    VkImageObj dst_image2(m_device);
+    dst_image2.init(64, 64, VK_FORMAT_R8G8B8A8_SINT, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0);
+
+    VkImageBlit blitRegion = {};
+    blitRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    blitRegion.srcSubresource.baseArrayLayer = 0;
+    blitRegion.srcSubresource.layerCount = 1;
+    blitRegion.srcSubresource.mipLevel = 0;
+    blitRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    blitRegion.dstSubresource.baseArrayLayer = 0;
+    blitRegion.dstSubresource.layerCount = 1;
+    blitRegion.dstSubresource.mipLevel = 0;
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_message);
+
+    // Unsigned int vs not an int
+    BeginCommandBuffer();
+    vkCmdBlitImage(m_commandBuffer->handle(), src_image.image(), src_image.layout(), dst_image.image(),
+                   dst_image.layout(), 1, &blitRegion, VK_FILTER_NEAREST);
+
+    m_errorMonitor->VerifyFound();
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, expected_message);
+
+    // Unsigned int vs signed int
+    vkCmdBlitImage(m_commandBuffer->handle(), src_image.image(), src_image.layout(), dst_image2.image(),
+                   dst_image2.layout(), 1, &blitRegion, VK_FILTER_NEAREST);
+
+    m_errorMonitor->VerifyFound();
+
+    EndCommandBuffer();
+}
+
+
 TEST_F(VkLayerTest, DSImageTransferGranularityTests) {
     VkResult err;
     bool pass;
@@ -3825,368 +2779,119 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, RenderPassInitialLayoutUndefined) {
-    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
-                     "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
-                     "the command buffer has prior knowledge of that "
-                     "attachment's layout.");
-
-    m_errorMonitor->ExpectSuccess();
-
+TEST_F(VkLayerTest, RenderPassPipelineSubpassMismatch) {
+    TEST_DESCRIPTION("Use a pipeline for the wrong subpass in a render pass instance");
     ASSERT_NO_FATAL_FAILURE(InitState());
 
-    // A renderpass with one color attachment.
-    VkAttachmentDescription attachment = {0,
-                                          VK_FORMAT_R8G8B8A8_UNORM,
-                                          VK_SAMPLE_COUNT_1_BIT,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_STORE,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                          VK_IMAGE_LAYOUT_UNDEFINED,
-                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
-
+    // A renderpass with two subpasses, both writing the same attachment.
+    VkAttachmentDescription attach[] = {
+        { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_DONT_CARE,
+            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+        },
+    };
+    VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+    VkSubpassDescription subpasses[] = {
+        { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+            1, &ref, nullptr, nullptr, 0, nullptr },
+        { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr,
+            1, &ref, nullptr, nullptr, 0, nullptr },
+    };
+    VkSubpassDependency dep = {
+        0, 1,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_DEPENDENCY_BY_REGION_BIT
+    };
+    VkRenderPassCreateInfo rpci = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr,
+        0, 1, attach, 2, subpasses, 1, &dep
+    };
     VkRenderPass rp;
     VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
     ASSERT_VK_SUCCESS(err);
 
-    // A compatible framebuffer.
     VkImageObj image(m_device);
-    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-
-    VkImageViewCreateInfo ivci = {
-        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-        nullptr,
-        0,
-        image.handle(),
-        VK_IMAGE_VIEW_TYPE_2D,
-        VK_FORMAT_R8G8B8A8_UNORM,
-        {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
-         VK_COMPONENT_SWIZZLE_IDENTITY},
-        {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
-    };
-    VkImageView view;
-    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
-    ASSERT_VK_SUCCESS(err);
-
-    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
-    VkFramebuffer fb;
-    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
-    ASSERT_VK_SUCCESS(err);
-
-    // Record a single command buffer which uses this renderpass twice. The
-    // bug is triggered at the beginning of the second renderpass, when the
-    // command buffer already has a layout recorded for the attachment.
-    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
-    BeginCommandBuffer();
-    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-    vkCmdEndRenderPass(m_commandBuffer->handle());
-    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-
-    m_errorMonitor->VerifyNotFound();
-
-    vkCmdEndRenderPass(m_commandBuffer->handle());
-    EndCommandBuffer();
-
-    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    vkDestroyImageView(m_device->device(), view, nullptr);
-}
-
-TEST_F(VkLayerTest, FramebufferBindingDestroyCommandPool) {
-    TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
-                     "command buffer, bind them together, then destroy "
-                     "command pool and framebuffer and verify there are no "
-                     "errors.");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    // A renderpass with one color attachment.
-    VkAttachmentDescription attachment = {0,
-                                          VK_FORMAT_R8G8B8A8_UNORM,
-                                          VK_SAMPLE_COUNT_1_BIT,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_STORE,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                          VK_IMAGE_LAYOUT_UNDEFINED,
-                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr};
-
-    VkRenderPass rp;
-    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
-    ASSERT_VK_SUCCESS(err);
-
-    // A compatible framebuffer.
-    VkImageObj image(m_device);
-    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-
-    VkImageViewCreateInfo ivci = {
-        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-        nullptr,
-        0,
-        image.handle(),
-        VK_IMAGE_VIEW_TYPE_2D,
-        VK_FORMAT_R8G8B8A8_UNORM,
-        {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
-         VK_COMPONENT_SWIZZLE_IDENTITY},
-        {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
-    };
-    VkImageView view;
-    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
-    ASSERT_VK_SUCCESS(err);
-
-    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
-    VkFramebuffer fb;
-    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
-    ASSERT_VK_SUCCESS(err);
-
-    // Explicitly create a command buffer to bind the FB to so that we can then
-    //  destroy the command pool in order to implicitly free command buffer
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer;
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 1;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
-
-    // Begin our cmd buffer with renderpass using our framebuffer
-    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
-    VkCommandBufferBeginInfo begin_info{};
-    begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-    vkBeginCommandBuffer(command_buffer, &begin_info);
-
-    vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-    vkCmdEndRenderPass(command_buffer);
-    vkEndCommandBuffer(command_buffer);
-    vkDestroyImageView(m_device->device(), view, nullptr);
-    // Destroy command pool to implicitly free command buffer
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, RenderPassSubpassZeroTransitionsApplied) {
-    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
-                     "transitions for the first subpass");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    // A renderpass with one color attachment.
-    VkAttachmentDescription attachment = {0,
-                                          VK_FORMAT_R8G8B8A8_UNORM,
-                                          VK_SAMPLE_COUNT_1_BIT,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_STORE,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                          VK_IMAGE_LAYOUT_UNDEFINED,
-                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
-
-    VkSubpassDependency dep = {0,
-                               0,
-                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                               VK_DEPENDENCY_BY_REGION_BIT};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
-
-    VkResult err;
-    VkRenderPass rp;
-    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
-    ASSERT_VK_SUCCESS(err);
-
-    // A compatible framebuffer.
-    VkImageObj image(m_device);
-    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-
-    VkImageViewCreateInfo ivci = {
-        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-        nullptr,
-        0,
-        image.handle(),
-        VK_IMAGE_VIEW_TYPE_2D,
-        VK_FORMAT_R8G8B8A8_UNORM,
-        {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
-         VK_COMPONENT_SWIZZLE_IDENTITY},
-        {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
-    };
-    VkImageView view;
-    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
-    ASSERT_VK_SUCCESS(err);
-
-    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
-    VkFramebuffer fb;
-    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
-    ASSERT_VK_SUCCESS(err);
-
-    // Record a single command buffer which issues a pipeline barrier w/
-    // image memory barrier for the attachment. This detects the previously
-    // missing tracking of the subpass layout by throwing a validation error
-    // if it doesn't occur.
-    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
-    BeginCommandBuffer();
-    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-
-    VkImageMemoryBarrier imb = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
-                                nullptr,
-                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                                VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-                                VK_QUEUE_FAMILY_IGNORED,
-                                VK_QUEUE_FAMILY_IGNORED,
-                                image.handle(),
-                                {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}};
-    vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
-                         &imb);
-
-    vkCmdEndRenderPass(m_commandBuffer->handle());
-    m_errorMonitor->VerifyNotFound();
-    EndCommandBuffer();
-
-    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    vkDestroyImageView(m_device->device(), view, nullptr);
-}
-
-TEST_F(VkLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
-    TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
-                     "is used as a depth/stencil framebuffer attachment, the "
-                     "aspectMask is ignored and both depth and stencil image "
-                     "subresources are used.");
-
-    VkFormatProperties format_properties;
-    vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
-    if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
-        return;
-    }
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkAttachmentDescription attachment = {0,
-                                          VK_FORMAT_D32_SFLOAT_S8_UINT,
-                                          VK_SAMPLE_COUNT_1_BIT,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_STORE,
-                                          VK_ATTACHMENT_LOAD_OP_DONT_CARE,
-                                          VK_ATTACHMENT_STORE_OP_DONT_CARE,
-                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
-                                          VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
-
-    VkAttachmentReference att_ref = {0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL};
-
-    VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr};
-
-    VkSubpassDependency dep = {0,
-                               0,
-                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                               VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                               VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
-                               VK_DEPENDENCY_BY_REGION_BIT};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep};
-
-    VkResult err;
-    VkRenderPass rp;
-    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
-    ASSERT_VK_SUCCESS(err);
-
-    VkImageObj image(m_device);
-    image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
-                         0x26, // usage
+    image.init_no_layout(32, 32, VK_FORMAT_R8G8B8A8_UNORM,
+                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
                          VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-    image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+    VkImageView imageView = image.targetView(VK_FORMAT_R8G8B8A8_UNORM);
 
-    VkImageViewCreateInfo ivci = {
-        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-        nullptr,
-        0,
-        image.handle(),
-        VK_IMAGE_VIEW_TYPE_2D,
-        VK_FORMAT_D32_SFLOAT_S8_UINT,
-        {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
-        {0x2, 0, 1, 0, 1},
+    VkFramebufferCreateInfo fbci = {
+        VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr,
+        0, rp, 1, &imageView, 32, 32, 1
     };
-    VkImageView view;
-    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
-    ASSERT_VK_SUCCESS(err);
-
-    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1};
     VkFramebuffer fb;
-    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    err = vkCreateFramebuffer(m_device->device(), &fbci, nullptr, &fb);
     ASSERT_VK_SUCCESS(err);
 
-    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
+    char const *vsSource =
+        "#version 450\n"
+        "void main() { gl_Position = vec4(1); }\n";
+    char const *fsSource =
+        "#version 450\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main() { color = vec4(1); }\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    VkViewport view_port = {};
+    m_viewports.push_back(view_port);
+    pipe.SetViewport(m_viewports);
+    VkRect2D rect = {};
+    m_scissors.push_back(rect);
+    pipe.SetScissor(m_scissors);
+
+    VkPipelineLayoutCreateInfo plci = {
+        VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr,
+        0, 0, nullptr, 0, nullptr
+    };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+    pipe.CreateVKPipeline(pl, rp);
+
     BeginCommandBuffer();
+
+    VkRenderPassBeginInfo rpbi = {
+        VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr,
+        rp, fb, { { 0, 0, }, { 32, 32 } }, 0, nullptr
+    };
+
+    // subtest 1: bind in the wrong subpass
     vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-
-    VkImageMemoryBarrier imb = {};
-    imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
-    imb.pNext = nullptr;
-    imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
-    imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-    imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
-    imb.srcQueueFamilyIndex = 0;
-    imb.dstQueueFamilyIndex = 0;
-    imb.image = image.handle();
-    imb.subresourceRange.aspectMask = 0x6;
-    imb.subresourceRange.baseMipLevel = 0;
-    imb.subresourceRange.levelCount = 0x1;
-    imb.subresourceRange.baseArrayLayer = 0;
-    imb.subresourceRange.layerCount = 0x1;
-
-    vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
-                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
-                         &imb);
+    vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "built for subpass 0 but used in subpass 1");
+    vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
+    m_errorMonitor->VerifyFound();
 
     vkCmdEndRenderPass(m_commandBuffer->handle());
-    EndCommandBuffer();
-    QueueCommandBuffer(false);
-    m_errorMonitor->VerifyNotFound();
 
+    // subtest 2: bind in correct subpass, then transition to next subpass
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdNextSubpass(m_commandBuffer->handle(), VK_SUBPASS_CONTENTS_INLINE);
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "built for subpass 0 but used in subpass 1");
+    vkCmdDraw(m_commandBuffer->handle(), 3, 1, 0, 0);
+    m_errorMonitor->VerifyFound();
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+
+    EndCommandBuffer();
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
     vkDestroyFramebuffer(m_device->device(), fb, nullptr);
     vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    vkDestroyImageView(m_device->device(), view, nullptr);
 }
 
 TEST_F(VkLayerTest, RenderPassInvalidRenderArea) {
@@ -4265,212 +2970,6 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, RenderPassTransitionsAttachmentUnused) {
-    TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
-                     "errors, when an attachment reference is "
-                     "VK_ATTACHMENT_UNUSED");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    // A renderpass with no attachments
-    VkAttachmentReference att_ref = {VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL};
-
-    VkSubpassDescription subpass = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr};
-
-    VkRenderPass rp;
-    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
-    ASSERT_VK_SUCCESS(err);
-
-    // A compatible framebuffer.
-    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1};
-    VkFramebuffer fb;
-    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
-    ASSERT_VK_SUCCESS(err);
-
-    // Record a command buffer which just begins and ends the renderpass. The
-    // bug manifests in BeginRenderPass.
-    VkRenderPassBeginInfo rpbi = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb, {{0, 0}, {32, 32}}, 0, nullptr};
-    BeginCommandBuffer();
-    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
-    vkCmdEndRenderPass(m_commandBuffer->handle());
-    m_errorMonitor->VerifyNotFound();
-    EndCommandBuffer();
-
-    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-}
-
-// This is a positive test. No errors are expected.
-TEST_F(VkLayerTest, StencilLoadOp) {
-    TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
-                     "CLEAR. stencil[Load|Store]Op used to be ignored.");
-    VkResult result = VK_SUCCESS;
-    VkImageFormatProperties formatProps;
-    vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
-                                             VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
-                                             &formatProps);
-    if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
-        return;
-    }
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
-    m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
-                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
-    VkAttachmentDescription att = {};
-    VkAttachmentReference ref = {};
-    att.format = depth_stencil_fmt;
-    att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
-    att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-    att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
-    att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
-    att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-    att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
-    VkClearValue clear;
-    clear.depthStencil.depth = 1.0;
-    clear.depthStencil.stencil = 0;
-    ref.attachment = 0;
-    ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-
-    VkSubpassDescription subpass = {};
-    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
-    subpass.flags = 0;
-    subpass.inputAttachmentCount = 0;
-    subpass.pInputAttachments = NULL;
-    subpass.colorAttachmentCount = 0;
-    subpass.pColorAttachments = NULL;
-    subpass.pResolveAttachments = NULL;
-    subpass.pDepthStencilAttachment = &ref;
-    subpass.preserveAttachmentCount = 0;
-    subpass.pPreserveAttachments = NULL;
-
-    VkRenderPass rp;
-    VkRenderPassCreateInfo rp_info = {};
-    rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
-    rp_info.attachmentCount = 1;
-    rp_info.pAttachments = &att;
-    rp_info.subpassCount = 1;
-    rp_info.pSubpasses = &subpass;
-    result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
-    ASSERT_VK_SUCCESS(result);
-
-    VkImageView *depthView = m_depthStencil->BindInfo();
-    VkFramebufferCreateInfo fb_info = {};
-    fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
-    fb_info.pNext = NULL;
-    fb_info.renderPass = rp;
-    fb_info.attachmentCount = 1;
-    fb_info.pAttachments = depthView;
-    fb_info.width = 100;
-    fb_info.height = 100;
-    fb_info.layers = 1;
-    VkFramebuffer fb;
-    result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
-    ASSERT_VK_SUCCESS(result);
-
-    VkRenderPassBeginInfo rpbinfo = {};
-    rpbinfo.clearValueCount = 1;
-    rpbinfo.pClearValues = &clear;
-    rpbinfo.pNext = NULL;
-    rpbinfo.renderPass = rp;
-    rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
-    rpbinfo.renderArea.extent.width = 100;
-    rpbinfo.renderArea.extent.height = 100;
-    rpbinfo.renderArea.offset.x = 0;
-    rpbinfo.renderArea.offset.y = 0;
-    rpbinfo.framebuffer = fb;
-
-    VkFence fence = {};
-    VkFenceCreateInfo fence_ci = {};
-    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fence_ci.pNext = nullptr;
-    fence_ci.flags = 0;
-    result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
-    ASSERT_VK_SUCCESS(result);
-
-    m_commandBuffer->BeginCommandBuffer();
-    m_commandBuffer->BeginRenderPass(rpbinfo);
-    m_commandBuffer->EndRenderPass();
-    m_commandBuffer->EndCommandBuffer();
-    m_commandBuffer->QueueCommandBuffer(fence);
-
-    VkImageObj destImage(m_device);
-    destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
-                   VK_IMAGE_TILING_OPTIMAL, 0);
-    VkImageMemoryBarrier barrier = {};
-    VkImageSubresourceRange range;
-    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
-    barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
-    barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
-    barrier.image = m_depthStencil->handle();
-    range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-    range.baseMipLevel = 0;
-    range.levelCount = 1;
-    range.baseArrayLayer = 0;
-    range.layerCount = 1;
-    barrier.subresourceRange = range;
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-    VkCommandBufferObj cmdbuf(m_device, m_commandPool);
-    cmdbuf.BeginCommandBuffer();
-    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
-                           &barrier);
-    barrier.srcAccessMask = 0;
-    barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
-    barrier.image = destImage.handle();
-    barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
-    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
-                           &barrier);
-    VkImageCopy cregion;
-    cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-    cregion.srcSubresource.mipLevel = 0;
-    cregion.srcSubresource.baseArrayLayer = 0;
-    cregion.srcSubresource.layerCount = 1;
-    cregion.srcOffset.x = 0;
-    cregion.srcOffset.y = 0;
-    cregion.srcOffset.z = 0;
-    cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
-    cregion.dstSubresource.mipLevel = 0;
-    cregion.dstSubresource.baseArrayLayer = 0;
-    cregion.dstSubresource.layerCount = 1;
-    cregion.dstOffset.x = 0;
-    cregion.dstOffset.y = 0;
-    cregion.dstOffset.z = 0;
-    cregion.extent.width = 100;
-    cregion.extent.height = 100;
-    cregion.extent.depth = 1;
-    cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
-                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
-    cmdbuf.EndCommandBuffer();
-
-    VkSubmitInfo submit_info;
-    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-    submit_info.pNext = NULL;
-    submit_info.waitSemaphoreCount = 0;
-    submit_info.pWaitSemaphores = NULL;
-    submit_info.pWaitDstStageMask = NULL;
-    submit_info.commandBufferCount = 1;
-    submit_info.pCommandBuffers = &cmdbuf.handle();
-    submit_info.signalSemaphoreCount = 0;
-    submit_info.pSignalSemaphores = NULL;
-
-    m_errorMonitor->ExpectSuccess();
-    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    m_errorMonitor->VerifyNotFound();
-
-    vkQueueWaitIdle(m_device->m_queue);
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
-}
-
 TEST_F(VkLayerTest, UnusedPreserveAttachment) {
     TEST_DESCRIPTION("Create a framebuffer where a subpass has a preserve "
                      "attachment reference of VK_ATTACHMENT_UNUSED");
@@ -4634,14 +3133,14 @@
 
 TEST_F(VkLayerTest, FramebufferCreateErrors) {
     TEST_DESCRIPTION("Hit errors when attempting to create a framebuffer :\n"
-                     " 1. Mismatch between fb & renderPass attachmentCount\n"
+                     " 1. Mismatch between framebuffer & renderPass attachmentCount\n"
                      " 2. Use a color image as depthStencil attachment\n"
-                     " 3. Mismatch fb & renderPass attachment formats\n"
-                     " 4. Mismatch fb & renderPass attachment #samples\n"
-                     " 5. FB attachment w/ non-1 mip-levels\n"
-                     " 6. FB attachment where dimensions don't match\n"
-                     " 7. FB attachment w/o identity swizzle\n"
-                     " 8. FB dimensions exceed physical device limits\n");
+                     " 3. Mismatch framebuffer & renderPass attachment formats\n"
+                     " 4. Mismatch framebuffer & renderPass attachment #samples\n"
+                     " 5. Framebuffer attachment w/ non-1 mip-levels\n"
+                     " 6. Framebuffer attachment where dimensions don't match\n"
+                     " 7. Framebuffer attachment w/o identity swizzle\n"
+                     " 8. framebuffer dimensions exceed physical device limits\n");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -4848,1300 +3347,6 @@
     vkDestroyRenderPass(m_device->device(), rp, NULL);
 }
 
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, WaitEventThenSet) {
-    TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
-
-    m_errorMonitor->ExpectSuccess();
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkEvent event;
-    VkEventCreateInfo event_create_info{};
-    event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
-    vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer;
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 1;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer, &begin_info);
-
-        vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
-                        nullptr, 0, nullptr);
-        vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
-        vkEndCommandBuffer(command_buffer);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer;
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = nullptr;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    { vkSetEvent(m_device->device(), event); }
-
-    vkQueueWaitIdle(queue);
-
-    vkDestroyEvent(m_device->device(), event, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, QueryAndCopySecondaryCommandBuffers) {
-    TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkQueryPool query_pool;
-    VkQueryPoolCreateInfo query_pool_create_info{};
-    query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
-    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
-    query_pool_create_info.queryCount = 1;
-    vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer;
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 1;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
-
-    VkCommandBuffer secondary_command_buffer;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    uint32_t qfi = 0;
-    VkBufferCreateInfo buff_create_info = {};
-    buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buff_create_info.size = 1024;
-    buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-    buff_create_info.queueFamilyIndexCount = 1;
-    buff_create_info.pQueueFamilyIndices = &qfi;
-
-    VkResult err;
-    VkBuffer buffer;
-    err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
-    ASSERT_VK_SUCCESS(err);
-    VkMemoryAllocateInfo mem_alloc = {};
-    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    mem_alloc.pNext = NULL;
-    mem_alloc.allocationSize = 1024;
-    mem_alloc.memoryTypeIndex = 0;
-
-    VkMemoryRequirements memReqs;
-    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
-    bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
-    if (!pass) {
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        return;
-    }
-
-    VkDeviceMemory mem;
-    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
-    ASSERT_VK_SUCCESS(err);
-    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
-    ASSERT_VK_SUCCESS(err);
-
-    VkCommandBufferInheritanceInfo hinfo = {};
-    hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
-    hinfo.renderPass = VK_NULL_HANDLE;
-    hinfo.subpass = 0;
-    hinfo.framebuffer = VK_NULL_HANDLE;
-    hinfo.occlusionQueryEnable = VK_FALSE;
-    hinfo.queryFlags = 0;
-    hinfo.pipelineStatistics = 0;
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        begin_info.pInheritanceInfo = &hinfo;
-        vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
-
-        vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
-        vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
-
-        vkEndCommandBuffer(secondary_command_buffer);
-
-        begin_info.pInheritanceInfo = nullptr;
-        vkBeginCommandBuffer(command_buffer, &begin_info);
-
-        vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
-        vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
-
-        vkEndCommandBuffer(command_buffer);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer;
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = nullptr;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-
-    vkQueueWaitIdle(queue);
-
-    vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-    vkDestroyBuffer(m_device->device(), buffer, NULL);
-    vkFreeMemory(m_device->device(), mem, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, QueryAndCopyMultipleCommandBuffers) {
-    TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkQueryPool query_pool;
-    VkQueryPoolCreateInfo query_pool_create_info{};
-    query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
-    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
-    query_pool_create_info.queryCount = 1;
-    vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    uint32_t qfi = 0;
-    VkBufferCreateInfo buff_create_info = {};
-    buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buff_create_info.size = 1024;
-    buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
-    buff_create_info.queueFamilyIndexCount = 1;
-    buff_create_info.pQueueFamilyIndices = &qfi;
-
-    VkResult err;
-    VkBuffer buffer;
-    err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
-    ASSERT_VK_SUCCESS(err);
-    VkMemoryAllocateInfo mem_alloc = {};
-    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
-    mem_alloc.pNext = NULL;
-    mem_alloc.allocationSize = 1024;
-    mem_alloc.memoryTypeIndex = 0;
-
-    VkMemoryRequirements memReqs;
-    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
-    bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
-    if (!pass) {
-        vkDestroyBuffer(m_device->device(), buffer, NULL);
-        return;
-    }
-
-    VkDeviceMemory mem;
-    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
-    ASSERT_VK_SUCCESS(err);
-    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
-    ASSERT_VK_SUCCESS(err);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
-        vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
-
-        vkEndCommandBuffer(command_buffer[0]);
-
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
-
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 2;
-        submit_info.pCommandBuffers = command_buffer;
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = nullptr;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-
-    vkQueueWaitIdle(queue);
-
-    vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-    vkDestroyBuffer(m_device->device(), buffer, NULL);
-    vkFreeMemory(m_device->device(), mem, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, ResetEventThenSet) {
-    TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkEvent event;
-    VkEventCreateInfo event_create_info{};
-    event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
-    vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer;
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 1;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer, &begin_info);
-
-        vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
-        vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
-                        nullptr, 0, nullptr, 0, nullptr);
-        vkEndCommandBuffer(command_buffer);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer;
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = nullptr;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
-                                                                            "command buffer.");
-        vkSetEvent(m_device->device(), event);
-        m_errorMonitor->VerifyFound();
-    }
-
-    vkQueueWaitIdle(queue);
-
-    vkDestroyEvent(m_device->device(), event, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoFencesThreeFrames) {
-    TEST_DESCRIPTION("Two command buffers with two separate fences are each "
-                     "run through a Submit & WaitForFences cycle 3 times. This "
-                     "previously revealed a bug so running this positive test "
-                     "to prevent a regression.");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
-
-    static const uint32_t NUM_OBJECTS = 2;
-    static const uint32_t NUM_FRAMES = 3;
-    VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
-    VkFence fences[NUM_OBJECTS] = {};
-
-    VkCommandPool cmd_pool;
-    VkCommandPoolCreateInfo cmd_pool_ci = {};
-    cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
-    ASSERT_VK_SUCCESS(err);
-
-    VkCommandBufferAllocateInfo cmd_buf_info = {};
-    cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    cmd_buf_info.commandPool = cmd_pool;
-    cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    cmd_buf_info.commandBufferCount = 1;
-
-    VkFenceCreateInfo fence_ci = {};
-    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    fence_ci.pNext = nullptr;
-    fence_ci.flags = 0;
-
-    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
-        err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
-        ASSERT_VK_SUCCESS(err);
-        err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
-        ASSERT_VK_SUCCESS(err);
-    }
-
-    for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
-        for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
-            // Create empty cmd buffer
-            VkCommandBufferBeginInfo cmdBufBeginDesc = {};
-            cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-
-            err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
-            ASSERT_VK_SUCCESS(err);
-            err = vkEndCommandBuffer(cmd_buffers[obj]);
-            ASSERT_VK_SUCCESS(err);
-
-            VkSubmitInfo submit_info = {};
-            submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-            submit_info.commandBufferCount = 1;
-            submit_info.pCommandBuffers = &cmd_buffers[obj];
-            // Submit cmd buffer and wait for fence
-            err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
-            ASSERT_VK_SUCCESS(err);
-            err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
-            ASSERT_VK_SUCCESS(err);
-            err = vkResetFences(m_device->device(), 1, &fences[obj]);
-            ASSERT_VK_SUCCESS(err);
-        }
-    }
-    m_errorMonitor->VerifyNotFound();
-    vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
-    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
-        vkDestroyFence(m_device->device(), fences[i], nullptr);
-    }
-}
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "submitted on separate queues followed by a QueueWaitIdle.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 1;
-        submit_info.pSignalSemaphores = &semaphore;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 1;
-        submit_info.pWaitSemaphores = &semaphore;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-
-    vkQueueWaitIdle(m_device->m_queue);
-
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "submitted on separate queues, the second having a fence"
-                     "followed by a QueueWaitIdle.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 1;
-        submit_info.pSignalSemaphores = &semaphore;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 1;
-        submit_info.pWaitSemaphores = &semaphore;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    }
-
-    vkQueueWaitIdle(m_device->m_queue);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "submitted on separate queues, the second having a fence"
-                     "followed by two consecutive WaitForFences calls on the same fence.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 1;
-        submit_info.pSignalSemaphores = &semaphore;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 1;
-        submit_info.pWaitSemaphores = &semaphore;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    }
-
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
-        printf("Test requires two queues, skipping\n");
-        return;
-    }
-
-    VkResult err;
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkQueue q0 = m_device->m_queue;
-    VkQueue q1 = nullptr;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
-    ASSERT_NE(q1, nullptr);
-
-    // An (empty) command buffer. We must have work in the first submission --
-    // the layer treats unfenced work differently from fenced work.
-    VkCommandPoolCreateInfo cpci = {VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0};
-    VkCommandPool pool;
-    err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
-    ASSERT_VK_SUCCESS(err);
-    VkCommandBufferAllocateInfo cbai = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
-                                        VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1};
-    VkCommandBuffer cb;
-    err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
-    ASSERT_VK_SUCCESS(err);
-    VkCommandBufferBeginInfo cbbi = {VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr};
-    err = vkBeginCommandBuffer(cb, &cbbi);
-    ASSERT_VK_SUCCESS(err);
-    err = vkEndCommandBuffer(cb);
-    ASSERT_VK_SUCCESS(err);
-
-    // A semaphore
-    VkSemaphoreCreateInfo sci = {VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
-    VkSemaphore s;
-    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
-    ASSERT_VK_SUCCESS(err);
-
-    // First submission, to q0
-    VkSubmitInfo s0 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s};
-
-    err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
-    ASSERT_VK_SUCCESS(err);
-
-    // Second submission, to q1, waiting on s
-    VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
-    VkSubmitInfo s1 = {VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr};
-
-    err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
-    ASSERT_VK_SUCCESS(err);
-
-    // Wait for q0 idle
-    err = vkQueueWaitIdle(q0);
-    ASSERT_VK_SUCCESS(err);
-
-    // Command buffer should have been completed (it was on q0); reset the pool.
-    vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
-
-    m_errorMonitor->VerifyNotFound();
-
-    // Force device completely idle and clean up resources
-    vkDeviceWaitIdle(m_device->device());
-    vkDestroyCommandPool(m_device->device(), pool, nullptr);
-    vkDestroySemaphore(m_device->device(), s, nullptr);
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "submitted on separate queues, the second having a fence, "
-                     "followed by a WaitForFences call.");
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
-        return;
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    VkQueue queue = VK_NULL_HANDLE;
-    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 1;
-        submit_info.pSignalSemaphores = &semaphore;
-        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 1;
-        submit_info.pWaitSemaphores = &semaphore;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    }
-
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "on the same queue, sharing a signal/wait semaphore, the "
-                     "second having a fence, "
-                     "followed by a WaitForFences call.");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 1;
-        submit_info.pSignalSemaphores = &semaphore;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 1;
-        submit_info.pWaitSemaphores = &semaphore;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    }
-
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "on the same queue, no fences, followed by a third QueueSubmit with NO "
-                     "SubmitInfos but with a fence, followed by a WaitForFences call.");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = VK_NULL_HANDLE;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 0;
-        submit_info.pWaitSemaphores = VK_NULL_HANDLE;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-
-    vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
-
-    VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-    ASSERT_VK_SUCCESS(err);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoQueueSubmitsOneQueueOneFence) {
-
-    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
-                     "on the same queue, the second having a fence, followed "
-                     "by a WaitForFences call.");
-
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[0];
-        submit_info.signalSemaphoreCount = 0;
-        submit_info.pSignalSemaphores = VK_NULL_HANDLE;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
-    }
-    {
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-        VkSubmitInfo submit_info{};
-        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info.commandBufferCount = 1;
-        submit_info.pCommandBuffers = &command_buffer[1];
-        submit_info.waitSemaphoreCount = 0;
-        submit_info.pWaitSemaphores = VK_NULL_HANDLE;
-        submit_info.pWaitDstStageMask = flags;
-        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
-    }
-
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-// This is a positive test.  No errors should be generated.
-TEST_F(VkLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
-
-    TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
-                     "QueueSubmit call followed by a WaitForFences call.");
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    m_errorMonitor->ExpectSuccess();
-
-    VkFence fence;
-    VkFenceCreateInfo fence_create_info{};
-    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
-    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
-
-    VkSemaphore semaphore;
-    VkSemaphoreCreateInfo semaphore_create_info{};
-    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
-    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
-
-    VkCommandPool command_pool;
-    VkCommandPoolCreateInfo pool_create_info{};
-    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
-    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
-    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
-    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
-
-    VkCommandBuffer command_buffer[2];
-    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
-    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
-    command_buffer_allocate_info.commandPool = command_pool;
-    command_buffer_allocate_info.commandBufferCount = 2;
-    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
-    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
-
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[0], &begin_info);
-
-        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
-                             nullptr, 0, nullptr, 0, nullptr);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[0]);
-    }
-    {
-        VkCommandBufferBeginInfo begin_info{};
-        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
-        vkBeginCommandBuffer(command_buffer[1], &begin_info);
-
-        VkViewport viewport{};
-        viewport.maxDepth = 1.0f;
-        viewport.minDepth = 0.0f;
-        viewport.width = 512;
-        viewport.height = 512;
-        viewport.x = 0;
-        viewport.y = 0;
-        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
-        vkEndCommandBuffer(command_buffer[1]);
-    }
-    {
-        VkSubmitInfo submit_info[2];
-        VkPipelineStageFlags flags[]{VK_PIPELINE_STAGE_ALL_COMMANDS_BIT};
-
-        submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info[0].pNext = NULL;
-        submit_info[0].commandBufferCount = 1;
-        submit_info[0].pCommandBuffers = &command_buffer[0];
-        submit_info[0].signalSemaphoreCount = 1;
-        submit_info[0].pSignalSemaphores = &semaphore;
-        submit_info[0].waitSemaphoreCount = 0;
-        submit_info[0].pWaitSemaphores = NULL;
-        submit_info[0].pWaitDstStageMask = 0;
-
-        submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-        submit_info[1].pNext = NULL;
-        submit_info[1].commandBufferCount = 1;
-        submit_info[1].pCommandBuffers = &command_buffer[1];
-        submit_info[1].waitSemaphoreCount = 1;
-        submit_info[1].pWaitSemaphores = &semaphore;
-        submit_info[1].pWaitDstStageMask = flags;
-        submit_info[1].signalSemaphoreCount = 0;
-        submit_info[1].pSignalSemaphores = NULL;
-        vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
-    }
-
-    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
-
-    vkDestroyFence(m_device->device(), fence, nullptr);
-    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
-    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
-    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, DynamicDepthBiasNotBound) {
     TEST_DESCRIPTION("Run a simple draw calls to validate failure when Depth Bias dynamic "
                      "state is required but not correctly bound.");
@@ -6170,7 +3375,7 @@
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     // Dynamic viewport state
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport state not set for this command buffer");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by pipeline state object, but were not provided");
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailViewport);
     m_errorMonitor->VerifyFound();
 }
@@ -6181,7 +3386,7 @@
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     // Dynamic scissor state
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor state not set for this command buffer");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, but were not provided");
     VKTriangleTest(bindStateVertShaderText, bindStateFragShaderText, BsoFailScissor);
     m_errorMonitor->VerifyFound();
 }
@@ -6431,7 +3636,7 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, InvalidDescriptorSet) {
+TEST_F(VkPositiveLayerTest, InvalidDescriptorSet) {
     // Attempt to bind an invalid Descriptor Set to a valid Command Buffer
     // ObjectTracker should catch this.
     // Create a valid cmd buffer
@@ -6663,18 +3868,13 @@
                      "due to a buffer dependency being destroyed.");
     ASSERT_NO_FATAL_FAILURE(InitState());
 
-    VkImageObj image(m_device);
-    image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
-               VK_IMAGE_TILING_OPTIMAL, 0);
-    ASSERT_TRUE(image.initialized());
-
     VkBuffer buffer;
     VkDeviceMemory mem;
     VkMemoryRequirements mem_reqs;
 
     VkBufferCreateInfo buf_info = {};
     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buf_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
     buf_info.size = 256;
     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
@@ -6697,18 +3897,8 @@
     err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
     ASSERT_VK_SUCCESS(err);
 
-    VkBufferImageCopy region = {};
-    region.bufferRowLength = 128;
-    region.bufferImageHeight = 128;
-    region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
-
-    region.imageSubresource.layerCount = 1;
-    region.imageExtent.height = 4;
-    region.imageExtent.width = 4;
-    region.imageExtent.depth = 1;
     m_commandBuffer->BeginCommandBuffer();
-    vkCmdCopyBufferToImage(m_commandBuffer->GetBufferHandle(), buffer, image.handle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1,
-                           &region);
+    vkCmdFillBuffer(m_commandBuffer->GetBufferHandle(), buffer, 0, VK_WHOLE_SIZE, 0);
     m_commandBuffer->EndCommandBuffer();
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer ");
@@ -6725,6 +3915,166 @@
     vkFreeMemory(m_device->handle(), mem, NULL);
 }
 
+TEST_F(VkLayerTest, InvalidCmdBufferBufferViewDestroyed) {
+    TEST_DESCRIPTION("Delete bufferView bound to cmd buffer, then attempt to submit cmd buffer.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count;
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding layout_binding;
+    layout_binding.binding = 0;
+    layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    layout_binding.descriptorCount = 1;
+    layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    layout_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &layout_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    VkDescriptorSet descriptor_set;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBuffer buffer;
+    uint32_t queue_family_index = 0;
+    VkBufferCreateInfo buffer_create_info = {};
+    buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buffer_create_info.size = 1024;
+    buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+    buffer_create_info.queueFamilyIndexCount = 1;
+    buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+    err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    VkMemoryRequirements memory_reqs;
+    VkDeviceMemory buffer_memory;
+
+    VkMemoryAllocateInfo memory_info = {};
+    memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    memory_info.allocationSize = 0;
+    memory_info.memoryTypeIndex = 0;
+
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+    memory_info.allocationSize = memory_reqs.size;
+    bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+    ASSERT_TRUE(pass);
+
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBufferView view;
+    VkBufferViewCreateInfo bvci = {};
+    bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+    bvci.buffer = buffer;
+    bvci.format = VK_FORMAT_R8_UNORM;
+    bvci.range = VK_WHOLE_SIZE;
+
+    err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptor_set;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    descriptor_write.pTexelBufferView = &view;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex { \n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
+                           "layout(location=0) out vec4 x;\n"
+                           "void main(){\n"
+                           "   x = imageLoad(s, 0);\n"
+                           "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot submit cmd buffer using deleted buffer view ");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " that is invalid because bound buffer view ");
+
+    BeginCommandBuffer();
+    VkViewport viewport = {0, 0, 16, 16, 0, 1};
+    vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
+    VkRect2D scissor = {{0, 0}, {16, 16}};
+    vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
+    // Bind pipeline to cmd buffer
+    vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
+                            &descriptor_set, 0, nullptr);
+    Draw(1, 0, 0, 0);
+    EndCommandBuffer();
+
+    // Delete BufferView in order to invalidate cmd buffer
+    vkDestroyBufferView(m_device->device(), view, NULL);
+    // Now attempt submit of cmd buffer
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    m_errorMonitor->VerifyFound();
+
+    // Clean-up
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
 TEST_F(VkLayerTest, InvalidCmdBufferImageDestroyed) {
     TEST_DESCRIPTION("Attempt to draw with a command buffer that is invalid "
                      "due to an image dependency being destroyed.");
@@ -6878,6 +4228,132 @@
     vkFreeMemory(m_device->device(), image_memory, nullptr);
 }
 
+TEST_F(VkLayerTest, FramebufferInUseDestroyedSignaled) {
+    TEST_DESCRIPTION("Delete in-use framebuffer.");
+    VkFormatProperties format_properties;
+    VkResult err = VK_SUCCESS;
+    vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkImageObj image(m_device);
+    image.init(256, 256, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+    VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
+
+    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Just use default renderpass with our framebuffer
+    m_renderPassBeginInfo.framebuffer = fb;
+    // Create Null cmd buffer for submit
+    BeginCommandBuffer();
+    EndCommandBuffer();
+    // Submit cmd buffer to put it in-flight
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    // Destroy framebuffer while in-flight
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete framebuffer 0x");
+    vkDestroyFramebuffer(m_device->device(), fb, NULL);
+    m_errorMonitor->VerifyFound();
+    // Wait for queue to complete so we can safely destroy everything
+    vkQueueWaitIdle(m_device->m_queue);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+}
+
+TEST_F(VkLayerTest, FramebufferImageInUseDestroyedSignaled) {
+    TEST_DESCRIPTION("Delete in-use image that's child of framebuffer.");
+    VkFormatProperties format_properties;
+    VkResult err = VK_SUCCESS;
+    vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_B8G8R8A8_UNORM, &format_properties);
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkImageCreateInfo image_ci = {};
+    image_ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_ci.pNext = NULL;
+    image_ci.imageType = VK_IMAGE_TYPE_2D;
+    image_ci.format = VK_FORMAT_B8G8R8A8_UNORM;
+    image_ci.extent.width = 256;
+    image_ci.extent.height = 256;
+    image_ci.extent.depth = 1;
+    image_ci.mipLevels = 1;
+    image_ci.arrayLayers = 1;
+    image_ci.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_ci.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_ci.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+    image_ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    image_ci.flags = 0;
+    VkImage image;
+    ASSERT_VK_SUCCESS(vkCreateImage(m_device->handle(), &image_ci, NULL, &image));
+
+    VkMemoryRequirements memory_reqs;
+    VkDeviceMemory image_memory;
+    bool pass;
+    VkMemoryAllocateInfo memory_info = {};
+    memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    memory_info.pNext = NULL;
+    memory_info.allocationSize = 0;
+    memory_info.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+    memory_info.allocationSize = memory_reqs.size;
+    pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image,
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_B8G8R8A8_UNORM,
+        {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A},
+        {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1},
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, m_renderPass, 1, &view, 256, 256, 1};
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Just use default renderpass with our framebuffer
+    m_renderPassBeginInfo.framebuffer = fb;
+    // Create Null cmd buffer for submit
+    BeginCommandBuffer();
+    EndCommandBuffer();
+    // Submit cmd buffer to put it (and attached imageView) in-flight
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    // Submit cmd buffer to put framebuffer and children in-flight
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    // Destroy image attached to framebuffer while in-flight
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image 0x");
+    vkDestroyImage(m_device->device(), image, NULL);
+    m_errorMonitor->VerifyFound();
+    // Wait for queue to complete so we can safely destroy image and other objects
+    vkQueueWaitIdle(m_device->m_queue);
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+    vkFreeMemory(m_device->device(), image_memory, nullptr);
+}
+
 TEST_F(VkLayerTest, ImageMemoryNotBound) {
     TEST_DESCRIPTION("Attempt to draw with an image which has not had memory bound to it.");
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -6915,9 +4391,9 @@
     err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &image_mem);
     ASSERT_VK_SUCCESS(err);
 
-    // Introduce error, do not call vkBindImageMemory(m_device->device(), image,
-    // image_mem, 0);
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "used without first calling vkBindImageMemory");
+    // Introduce error, do not call vkBindImageMemory(m_device->device(), image, image_mem, 0);
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
 
     m_commandBuffer->BeginCommandBuffer();
     VkClearColorValue ccv;
@@ -6954,7 +4430,7 @@
 
     VkBufferCreateInfo buf_info = {};
     buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buf_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
     buf_info.size = 256;
     buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
     VkResult err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
@@ -6974,9 +4450,9 @@
     err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
     ASSERT_VK_SUCCESS(err);
 
-    // Introduce failure by not calling vkBindBufferMemory(m_device->device(),
-    // buffer, mem, 0);
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "used without first calling vkBindBufferMemory");
+    // Introduce failure by not calling vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
     VkBufferImageCopy region = {};
     region.bufferRowLength = 128;
     region.bufferImageHeight = 128;
@@ -7078,9 +4554,6 @@
     vp_state_ci.scissorCount = 1;
     VkRect2D scissors = {}; // Dummy scissors to point to
     vp_state_ci.pScissors = &scissors;
-    // No dynamic state
-    VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
-    dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 
     VkPipelineShaderStageCreateInfo shaderStages[2];
     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
@@ -7100,6 +4573,8 @@
 
     VkPipelineRasterizationStateCreateInfo rs_ci = {};
     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+    rs_ci.rasterizerDiscardEnable = true;
+    rs_ci.lineWidth = 1.0f;
 
     VkPipelineColorBlendAttachmentState att = {};
     att.blendEnable = VK_FALSE;
@@ -7119,7 +4594,6 @@
     gp_ci.pViewportState = &vp_state_ci;
     gp_ci.pRasterizationState = &rs_ci;
     gp_ci.pColorBlendState = &cb_ci;
-    gp_ci.pDynamicState = &dyn_state_ci;
     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
     gp_ci.layout = pipeline_layout;
     gp_ci.renderPass = renderPass();
@@ -7568,6 +5042,317 @@
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
+TEST_F(VkLayerTest, DescriptorPoolInUseDestroyedSignaled) {
+    TEST_DESCRIPTION("Delete a DescriptorPool with a DescriptorSet that is in use.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptor_set;
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create image to update the descriptor with
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageView view = image.targetView(VK_FORMAT_B8G8R8A8_UNORM);
+    // Create Sampler
+    VkSamplerCreateInfo sampler_ci = {};
+    sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+    sampler_ci.pNext = NULL;
+    sampler_ci.magFilter = VK_FILTER_NEAREST;
+    sampler_ci.minFilter = VK_FILTER_NEAREST;
+    sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.mipLodBias = 1.0;
+    sampler_ci.anisotropyEnable = VK_FALSE;
+    sampler_ci.maxAnisotropy = 1;
+    sampler_ci.compareEnable = VK_FALSE;
+    sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
+    sampler_ci.minLod = 1.0;
+    sampler_ci.maxLod = 1.0;
+    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+    sampler_ci.unnormalizedCoordinates = VK_FALSE;
+    VkSampler sampler;
+    err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
+    ASSERT_VK_SUCCESS(err);
+    // Update descriptor with image and sampler
+    VkDescriptorImageInfo img_info = {};
+    img_info.sampler = sampler;
+    img_info.imageView = view;
+    img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+    VkWriteDescriptorSet descriptor_write;
+    memset(&descriptor_write, 0, sizeof(descriptor_write));
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptor_set;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    descriptor_write.pImageInfo = &img_info;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    // Create PSO to be used for draw-time errors below
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex { \n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(set=0, binding=0) uniform sampler2D s;\n"
+                           "layout(location=0) out vec4 x;\n"
+                           "void main(){\n"
+                           "   x = texture(s, vec2(1));\n"
+                           "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    BeginCommandBuffer();
+    vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
+                            &descriptor_set, 0, NULL);
+    Draw(1, 0, 0, 0);
+    EndCommandBuffer();
+    // Submit cmd buffer to put pool in-flight
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    // Destroy pool while in-flight, causing error
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete descriptor pool ");
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+    m_errorMonitor->VerifyFound();
+    vkQueueWaitIdle(m_device->m_queue);
+    // Cleanup
+    vkDestroySampler(m_device->device(), sampler, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, DescriptorImageUpdateNoMemoryBound) {
+    TEST_DESCRIPTION("Attempt an image descriptor set update where image's bound memory has been freed.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptorSet;
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptorSet);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create images to update the descriptor with
+    VkImage image;
+    const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+    const int32_t tex_width = 32;
+    const int32_t tex_height = 32;
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = tex_format;
+    image_create_info.extent.width = tex_width;
+    image_create_info.extent.height = tex_height;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+    image_create_info.flags = 0;
+    err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+    // Initially bind memory to avoid error at bind view time. We'll break binding before update.
+    VkMemoryRequirements memory_reqs;
+    VkDeviceMemory image_memory;
+    bool pass;
+    VkMemoryAllocateInfo memory_info = {};
+    memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    memory_info.pNext = NULL;
+    memory_info.allocationSize = 0;
+    memory_info.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+    // Allocate enough memory for image
+    memory_info.allocationSize = memory_reqs.size;
+    pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageViewCreateInfo image_view_create_info = {};
+    image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    image_view_create_info.image = image;
+    image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    image_view_create_info.format = tex_format;
+    image_view_create_info.subresourceRange.layerCount = 1;
+    image_view_create_info.subresourceRange.baseMipLevel = 0;
+    image_view_create_info.subresourceRange.levelCount = 1;
+    image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+    // Create Samplers
+    VkSamplerCreateInfo sampler_ci = {};
+    sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+    sampler_ci.pNext = NULL;
+    sampler_ci.magFilter = VK_FILTER_NEAREST;
+    sampler_ci.minFilter = VK_FILTER_NEAREST;
+    sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.mipLodBias = 1.0;
+    sampler_ci.anisotropyEnable = VK_FALSE;
+    sampler_ci.maxAnisotropy = 1;
+    sampler_ci.compareEnable = VK_FALSE;
+    sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
+    sampler_ci.minLod = 1.0;
+    sampler_ci.maxLod = 1.0;
+    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+    sampler_ci.unnormalizedCoordinates = VK_FALSE;
+    VkSampler sampler;
+    err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
+    ASSERT_VK_SUCCESS(err);
+    // Update descriptor with image and sampler
+    VkDescriptorImageInfo img_info = {};
+    img_info.sampler = sampler;
+    img_info.imageView = view;
+    img_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+    VkWriteDescriptorSet descriptor_write;
+    memset(&descriptor_write, 0, sizeof(descriptor_write));
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptorSet;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    descriptor_write.pImageInfo = &img_info;
+    // Break memory binding and attempt update
+    vkFreeMemory(m_device->device(), image_memory, nullptr);
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " previously bound memory was freed. Memory must not be freed prior to this operation.");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+    // Cleanup
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkDestroySampler(m_device->device(), sampler, NULL);
+    vkDestroyImageView(m_device->device(), view, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
 TEST_F(VkLayerTest, InvalidPipeline) {
     // Attempt to bind an invalid Pipeline to a valid Command Buffer
     // ObjectTracker should catch this.
@@ -7575,20 +5360,22 @@
     // call vkCmdBindPipeline w/ false Pipeline
     uint64_t fake_pipeline_handle = 0xbaad6001;
     VkPipeline bad_pipeline = reinterpret_cast<VkPipeline &>(fake_pipeline_handle);
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
     ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline Object 0xbaad6001");
     BeginCommandBuffer();
     vkCmdBindPipeline(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, bad_pipeline);
     m_errorMonitor->VerifyFound();
+
     // Now issue a draw call with no pipeline bound
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
-
-    BeginCommandBuffer();
     Draw(1, 0, 0, 0);
     m_errorMonitor->VerifyFound();
+
     // Finally same check once more but with Dispatch/Compute
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "At Draw/Dispatch time no valid VkPipeline is bound!");
-    BeginCommandBuffer();
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // must be outside renderpass
     vkCmdDispatch(m_commandBuffer->GetBufferHandle(), 0, 0, 0);
     m_errorMonitor->VerifyFound();
 }
@@ -7742,11 +5529,11 @@
 }
 
 TEST_F(VkLayerTest, CreateBufferViewNoMemoryBoundToBuffer) {
-    TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has"
-                     " no memory bound to it.");
+    TEST_DESCRIPTION("Attempt to create a buffer view with a buffer that has no memory bound to it.");
 
     VkResult err;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "used without first calling vkBindBufferMemory");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -7754,7 +5541,7 @@
     // a buffer view.
     VkBufferCreateInfo buff_ci = {};
     buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
-    buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT;
     buff_ci.size = 256;
     buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
     VkBuffer buffer;
@@ -7951,7 +5738,10 @@
     TEST_DESCRIPTION("Attempt to update a descriptor with a non-sparse buffer "
                      "that doesn't have memory bound");
     VkResult err;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, " used without first calling vkBindBufferMemory.");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " used with no memory bound. Memory should be bound by calling vkBindBufferMemory().");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         "vkUpdateDescriptorsSets() failed write update validation for Descriptor Set 0x");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitViewport());
@@ -8062,10 +5852,10 @@
         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
          "vkCreatePipelineLayout() call has push constants index 0 with "
          "size 1."},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 1, 1},
+        {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
          "vkCreatePipelineLayout() call has push constants index 0 with "
          "size 1."},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 1, 0},
+        {{VK_SHADER_STAGE_VERTEX_BIT, 4, 0},
          "vkCreatePipelineLayout() call has push constants index 0 with "
          "size 0."},
         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
@@ -8077,7 +5867,7 @@
         {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big},
          "vkCreatePipelineLayout() call has push constants "
          "index 0 with offset "},
-        {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 0},
+        {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 4},
          "vkCreatePipelineLayout() call has push constants index 0 "
          "with offset "},
         {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020},
@@ -8103,7 +5893,9 @@
     pc_range.offset = 0;
     pc_range.size = 16;
     pc_range.stageFlags = 0;
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCreatePipelineLayout() call has no stageFlags set.");
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "vkCreatePipelineLayout: value of pCreateInfo->pPushConstantRanges[0].stageFlags must not be 0");
     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
     m_errorMonitor->VerifyFound();
     if (VK_SUCCESS == err) {
@@ -8123,17 +5915,14 @@
            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
            {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
-          "vkCreatePipelineLayout() call has push constants with overlapping "
-          "ranges: 0:[0, 4), 1:[0, 4)"},
+          "vkCreatePipelineLayout() call has push constants with overlapping ranges:"},
          {
              {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
               {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
-             "vkCreatePipelineLayout() call has push constants with "
-             "overlapping "
-             "ranges: 3:[12, 20), 4:[16, 20)",
+             "vkCreatePipelineLayout() call has push constants with overlapping ranges: 3:[12, 20), 4:[16, 20)",
          },
          {
              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
@@ -8141,9 +5930,7 @@
               {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
-             "vkCreatePipelineLayout() call has push constants with "
-             "overlapping "
-             "ranges: 0:[16, 20), 1:[12, 20)",
+             "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 1:[12, 20)",
          },
          {
              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
@@ -8151,9 +5938,7 @@
               {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
               {VK_SHADER_STAGE_VERTEX_BIT, 12, 8},
               {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
-             "vkCreatePipelineLayout() call has push constants with "
-             "overlapping "
-             "ranges: 0:[16, 20), 3:[12, 20)",
+             "vkCreatePipelineLayout() call has push constants with overlapping ranges: 0:[16, 20), 3:[12, 20)",
          },
          {
              {{VK_SHADER_STAGE_VERTEX_BIT, 16, 4},
@@ -8161,9 +5946,7 @@
               {VK_SHADER_STAGE_VERTEX_BIT, 4, 96},
               {VK_SHADER_STAGE_VERTEX_BIT, 40, 8},
               {VK_SHADER_STAGE_VERTEX_BIT, 52, 4}},
-             "vkCreatePipelineLayout() call has push constants with "
-             "overlapping "
-             "ranges: 0:[16, 20), 2:[4, 100)",
+             "vkCreatePipelineLayout() call has push constants with overlapping ranges:",
          }}};
 
     for (const auto &iter : overlapping_range_tests) {
@@ -8177,46 +5960,21 @@
         }
     }
 
-    // Run some positive tests to make sure overlap checking in the layer is OK
-    const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = {{{{{VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 4, 4},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 8, 4},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 12, 4},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 16, 4}},
-                                                                                   ""},
-                                                                                  {{{VK_SHADER_STAGE_VERTEX_BIT, 92, 24},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 80, 4},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 64, 8},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 4, 16},
-                                                                                    {VK_SHADER_STAGE_VERTEX_BIT, 0, 4}},
-                                                                                   ""}}};
-    for (const auto &iter : overlapping_range_tests_pos) {
-        pipeline_layout_ci.pPushConstantRanges = iter.ranges;
-        m_errorMonitor->ExpectSuccess();
-        err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
-        m_errorMonitor->VerifyNotFound();
-        if (VK_SUCCESS == err) {
-            vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
-        }
-    }
-
     //
     // CmdPushConstants tests
     //
     const uint8_t dummy_values[100] = {};
 
     // Check for invalid offset and size and if range is within layout range(s)
-    const std::array<PipelineLayoutTestCase, 16> cmd_range_tests = {{
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0},
-         "vkCmdPushConstants() call has push constants with size 0. Size "
-         "must be greater than zero and a multiple of 4."},
+    const std::array<PipelineLayoutTestCase, 11> cmd_range_tests = {{
+        {{VK_SHADER_STAGE_VERTEX_BIT, 0, 0}, "vkCmdPushConstants: parameter size must be greater than 0"},
         {{VK_SHADER_STAGE_VERTEX_BIT, 0, 1},
          "vkCmdPushConstants() call has push constants with size 1. Size "
          "must be greater than zero and a multiple of 4."},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 1, 1},
+        {{VK_SHADER_STAGE_VERTEX_BIT, 4, 1},
          "vkCmdPushConstants() call has push constants with size 1. Size "
          "must be greater than zero and a multiple of 4."},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 1, 0},
+        {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
          "vkCmdPushConstants() call has push constants with offset 1. "
          "Offset must be a multiple of 4."},
         {{VK_SHADER_STAGE_VERTEX_BIT, 1, 4},
@@ -8240,14 +5998,11 @@
         {{VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0, 16},
          "vkCmdPushConstants() stageFlags = 0x3 do not match the stageFlags in "
          "any of the ranges in pipeline layout"},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0, too_big}, "vkCmdPushConstants() call has push constants with offset "},
-        {{VK_SHADER_STAGE_VERTEX_BIT, too_big, too_big}, "vkCmdPushConstants() call has push constants with offset "},
-        {{VK_SHADER_STAGE_VERTEX_BIT, too_big, 0}, "vkCmdPushConstants() call has push constants with offset "},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0xFFFFFFF0, 0x00000020}, "vkCmdPushConstants() call has push constants with offset "},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0x00000020, 0xFFFFFFF0}, "vkCmdPushConstants() call has push constants with offset "},
     }};
 
-    // Two ranges for testing robustness
+    BeginCommandBuffer();
+
+    // Setup ranges: [0,16) [64,80)
     const VkPushConstantRange pc_range2[] = {
         {VK_SHADER_STAGE_VERTEX_BIT, 64, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
     };
@@ -8255,7 +6010,6 @@
     pipeline_layout_ci.pPushConstantRanges = pc_range2;
     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
     ASSERT_VK_SUCCESS(err);
-    BeginCommandBuffer();
     for (const auto &iter : cmd_range_tests) {
         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
@@ -8264,11 +6018,9 @@
     }
 
     // Check for invalid stage flag
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants() call has no stageFlags set.");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdPushConstants: value of stageFlags must not be 0");
     vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, 0, 0, 16, dummy_values);
     m_errorMonitor->VerifyFound();
-    EndCommandBuffer();
-    vkResetCommandBuffer(m_commandBuffer->GetBufferHandle(), 0);
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
 
     // overlapping range tests with cmd
@@ -8283,52 +6035,24 @@
          "vkCmdPushConstants() Push constant range [40, 56) with stageFlags = "
          "0x1 not within flag-matching ranges in pipeline layout"},
     }};
+    // Setup ranges:  [0,16), [20,36), [36,44), [44,52), [80,92)
     const VkPushConstantRange pc_range3[] = {
-        {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},  {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},
-        {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},  {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
-        {VK_SHADER_STAGE_VERTEX_BIT, 56, 28},
+        {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},
+        {VK_SHADER_STAGE_VERTEX_BIT, 80, 12}, {VK_SHADER_STAGE_VERTEX_BIT, 36, 8},
     };
     pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range3) / sizeof(VkPushConstantRange);
     pipeline_layout_ci.pPushConstantRanges = pc_range3;
     err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
     ASSERT_VK_SUCCESS(err);
-    BeginCommandBuffer();
     for (const auto &iter : cmd_overlap_tests) {
         m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, iter.msg);
         vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
                            iter.range.size, dummy_values);
         m_errorMonitor->VerifyFound();
     }
-    EndCommandBuffer();
-    vkResetCommandBuffer(m_commandBuffer->GetBufferHandle(), 0);
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
 
-    // positive overlapping range tests with cmd
-    const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = {{
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0, 16}, ""},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 0, 4}, ""},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 20, 12}, ""},
-        {{VK_SHADER_STAGE_VERTEX_BIT, 56, 36}, ""},
-    }};
-    const VkPushConstantRange pc_range4[] = {
-        {VK_SHADER_STAGE_VERTEX_BIT, 0, 64}, {VK_SHADER_STAGE_VERTEX_BIT, 20, 16}, {VK_SHADER_STAGE_VERTEX_BIT, 0, 16},
-        {VK_SHADER_STAGE_VERTEX_BIT, 0, 4},  {VK_SHADER_STAGE_VERTEX_BIT, 44, 8},  {VK_SHADER_STAGE_VERTEX_BIT, 80, 12},
-        {VK_SHADER_STAGE_VERTEX_BIT, 36, 8}, {VK_SHADER_STAGE_VERTEX_BIT, 56, 28},
-    };
-    pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
-    pipeline_layout_ci.pPushConstantRanges = pc_range4;
-    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
-    ASSERT_VK_SUCCESS(err);
-    BeginCommandBuffer();
-    for (const auto &iter : cmd_overlap_tests_pos) {
-        m_errorMonitor->ExpectSuccess();
-        vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
-                           iter.range.size, dummy_values);
-        m_errorMonitor->VerifyNotFound();
-    }
     EndCommandBuffer();
-    vkResetCommandBuffer(m_commandBuffer->GetBufferHandle(), 0);
-    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
 }
 
 TEST_F(VkLayerTest, DescriptorSetCompatibility) {
@@ -8564,9 +6288,9 @@
     imageInfo[1].imageView = view;
     imageInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
     imageInfo[2].imageView = view;
-    imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    imageInfo[2].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
     imageInfo[3].imageView = view;
-    imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    imageInfo[3].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
 
     static const uint32_t NUM_SET_UPDATES = 3;
     VkWriteDescriptorSet descriptor_write[NUM_SET_UPDATES] = {};
@@ -8713,8 +6437,6 @@
         vkDestroyDescriptorSetLayout(m_device->device(), ds_layout[i], NULL);
     }
     vkDestroyDescriptorSetLayout(m_device->device(), ds_layout_fs_only, NULL);
-    vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &ds0_fs_only);
-    vkFreeDescriptorSets(m_device->device(), ds_pool, NUM_SETS, descriptorSet);
     vkDestroyBuffer(m_device->device(), dyub, NULL);
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
     vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
@@ -8774,7 +6496,7 @@
     // Then cause 2 errors for attempting to reset CB w/o having
     // VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT set for the pool from
     // which CBs were allocated. Note that this bit is off by default.
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on CB");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot call Begin on command buffer");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -8814,7 +6536,7 @@
     // Attempt to Create Gfx Pipeline w/o a VS
     VkResult err;
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vtx Shader required");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Invalid Pipeline CreateInfo State: Vertex Shader required");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -9421,7 +7143,7 @@
     // Now hit second fail case where we set scissor w/ different count than PSO
     // First need to successfully create the PSO from above by setting
     // pViewports
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by PSO, ");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic scissor(s) 0 are used by pipeline state object, ");
 
     VkViewport vp = {}; // Just need dummy vp to point to
     vp_state_ci.pViewports = &vp;
@@ -9584,7 +7306,7 @@
     // Now hit second fail case where we set scissor w/ different count than PSO
     // First need to successfully create the PSO from above by setting
     // pViewports
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by PSO, ");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Dynamic viewport(s) 0 are used by pipeline state object, ");
 
     VkRect2D sc = {}; // Just need dummy vp to point to
     vp_state_ci.pScissors = &sc;
@@ -9815,27 +7537,6 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    BeginCommandBuffer();                                   // framework implicitly begins the renderpass.
-    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // end implicit.
-
-    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
-    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
-    m_errorMonitor->VerifyNotFound();
-    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
-    m_errorMonitor->VerifyNotFound();
-    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
-    m_errorMonitor->VerifyNotFound();
-
-    m_commandBuffer->EndCommandBuffer();
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, RenderPassClearOpMismatch) {
     TEST_DESCRIPTION("Begin a renderPass where clearValueCount is less than"
                      "the number of renderPass attachments that use loadOp"
@@ -10306,6 +8007,46 @@
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, LayoutFromPresentWithoutAccessMemoryRead) {
+    // Transition an image away from PRESENT_SRC_KHR without ACCESS_MEMORY_READ in srcAccessMask
+
+    m_errorMonitor->SetDesiredFailureMsg(
+        VK_DEBUG_REPORT_WARNING_BIT_EXT,
+        "must have required access bit");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageMemoryBarrier barrier = {};
+    VkImageSubresourceRange range;
+    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    barrier.srcAccessMask = 0;
+    barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+    barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+    barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+    barrier.image = image.handle();
+    range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    range.baseMipLevel = 0;
+    range.levelCount = 1;
+    range.baseArrayLayer = 0;
+    range.layerCount = 1;
+    barrier.subresourceRange = range;
+    VkCommandBufferObj cmdbuf(m_device, m_commandPool);
+    cmdbuf.BeginCommandBuffer();
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
+                           &barrier);
+    barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+    barrier.srcAccessMask = 0;
+    barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
+                           &barrier);
+
+    m_errorMonitor->VerifyFound();
+}
+
 TEST_F(VkLayerTest, IdxBufferAlignmentError) {
     // Bind a BeginRenderPass within an active RenderPass
     VkResult err;
@@ -10365,19 +8106,23 @@
 }
 
 TEST_F(VkLayerTest, ExecuteCommandsPrimaryCB) {
-    TEST_DESCRIPTION("Attempt vkCmdExecuteCommands w/ a primary cmd buffer"
+TEST_DESCRIPTION("Attempt vkCmdExecuteCommands with a primary command buffer"
                      " (should only be secondary)");
 
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
-
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
-    BeginCommandBuffer();
+    // An empty primary command buffer
+    VkCommandBufferObj cb(m_device, m_commandPool);
+    cb.BeginCommandBuffer();
+    cb.EndCommandBuffer();
 
-    VkCommandBuffer primCB = m_commandBuffer->GetBufferHandle();
-    vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &primCB);
+    m_commandBuffer->BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &renderPassBeginInfo(), VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+    VkCommandBuffer handle = cb.handle();
 
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "vkCmdExecuteCommands() called w/ Primary Cmd Buffer ");
+    vkCmdExecuteCommands(m_commandBuffer->handle(), 1, &handle);
     m_errorMonitor->VerifyFound();
 }
 
@@ -11559,7 +9304,7 @@
 TEST_F(VkLayerTest, RenderPassIncompatible) {
     TEST_DESCRIPTION("Hit RenderPass incompatible cases. "
                      "Initial case is drawing with an active renderpass that's "
-                     "not compatible with the bound PSO's creation renderpass");
+                     "not compatible with the bound pipeline state object's creation renderpass");
     VkResult err;
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -11770,7 +9515,7 @@
     VkResult err;
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
-                                         "vkCmdClearAttachments() issued on CB object ");
+                                         "vkCmdClearAttachments() issued on command buffer object ");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -12112,8 +9857,7 @@
                                                         "is 0x";
     const char *bind_null_buffer_message = "In vkBindBufferMemory, attempting"
                                            " to Bind Obj(0x";
-    const char *free_invalid_buffer_message = "Request to delete memory "
-                                              "object 0x";
+    const char *free_invalid_buffer_message = "Invalid Device Memory Object 0x";
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitViewport());
@@ -12415,47 +10159,103 @@
     vkDestroyImage(m_device->device(), dst_image, NULL);
 }
 
-TEST_F(VkLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
-    TEST_DESCRIPTION("Positive test where we create a renderpass with an "
-                     "attachment that uses LOAD_OP_CLEAR, the first subpass "
-                     "has a valid layout, and a second subpass then uses a "
-                     "valid *READ_ONLY* layout.");
-    m_errorMonitor->ExpectSuccess();
+TEST_F(VkLayerTest, InvalidStorageImageLayout) {
+    TEST_DESCRIPTION("Attempt to update a STORAGE_IMAGE descriptor w/o GENERAL layout.");
+    VkResult err;
+
     ASSERT_NO_FATAL_FAILURE(InitState());
 
-    VkAttachmentReference attach[2] = {};
-    attach[0].attachment = 0;
-    attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-    attach[1].attachment = 0;
-    attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
-    VkSubpassDescription subpasses[2] = {};
-    // First subpass clears DS attach on load
-    subpasses[0].pDepthStencilAttachment = &attach[0];
-    // 2nd subpass reads in DS as input attachment
-    subpasses[1].inputAttachmentCount = 1;
-    subpasses[1].pInputAttachments = &attach[1];
-    VkAttachmentDescription attach_desc = {};
-    attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
-    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
-    attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
-    attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-    attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
-    attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
-    attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
-    attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
-    VkRenderPassCreateInfo rpci = {};
-    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
-    rpci.attachmentCount = 1;
-    rpci.pAttachments = &attach_desc;
-    rpci.subpassCount = 2;
-    rpci.pSubpasses = subpasses;
+    const VkFormat tex_format = VK_FORMAT_R8G8B8A8_UNORM;
+    VkImageTiling tiling;
+    VkFormatProperties format_properties;
+    vkGetPhysicalDeviceFormatProperties(gpu(), tex_format, &format_properties);
+    if (format_properties.linearTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
+        tiling = VK_IMAGE_TILING_LINEAR;
+    } else if (format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) {
+        tiling = VK_IMAGE_TILING_OPTIMAL;
+    } else {
+        printf("Device does not support VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; "
+               "skipped.\n");
+        return;
+    }
 
-    // Now create RenderPass and verify no errors
-    VkRenderPass rp;
-    vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
-    m_errorMonitor->VerifyNotFound();
+    VkDescriptorPoolSize ds_type = {};
+    ds_type.type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+    ds_type.descriptorCount = 1;
 
-    vkDestroyRenderPass(m_device->device(), rp, NULL);
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type;
+    ds_pool_ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+
+    VkDescriptorPool ds_pool;
+    err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding dsl_binding = {};
+    dsl_binding.binding = 0;
+    dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+    dsl_binding.descriptorCount = 1;
+    dsl_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    dsl_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &dsl_binding;
+
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    VkDescriptorSet descriptor_set;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageObj image(m_device);
+    image.init(32, 32, tex_format, VK_IMAGE_USAGE_STORAGE_BIT, tiling, 0);
+    ASSERT_TRUE(image.initialized());
+    VkImageView view = image.targetView(tex_format);
+
+    VkDescriptorImageInfo image_info = {};
+    image_info.imageView = view;
+    image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptor_set;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
+    descriptor_write.pImageInfo = &image_info;
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " of VK_DESCRIPTOR_TYPE_STORAGE_IMAGE type is being updated with layout "
+                                         "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL but according to spec ");
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
 }
 
 TEST_F(VkLayerTest, SimultaneousUse) {
@@ -12465,7 +10265,7 @@
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
 
-    const char *simultaneous_use_message1 = "w/o VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
+    const char *simultaneous_use_message1 = "without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set!";
     const char *simultaneous_use_message2 = "does not have VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set and "
                                             "will cause primary command buffer";
 
@@ -12756,6 +10556,328 @@
     vkDestroyPipelineLayout(m_device->handle(), pipeline_layout, nullptr);
 }
 
+TEST_F(VkLayerTest, ImageViewInUseDestroyedSignaled) {
+    TEST_DESCRIPTION("Delete in-use imageView.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count;
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkSamplerCreateInfo sampler_ci = {};
+    sampler_ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
+    sampler_ci.pNext = NULL;
+    sampler_ci.magFilter = VK_FILTER_NEAREST;
+    sampler_ci.minFilter = VK_FILTER_NEAREST;
+    sampler_ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST;
+    sampler_ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
+    sampler_ci.mipLodBias = 1.0;
+    sampler_ci.anisotropyEnable = VK_FALSE;
+    sampler_ci.maxAnisotropy = 1;
+    sampler_ci.compareEnable = VK_FALSE;
+    sampler_ci.compareOp = VK_COMPARE_OP_NEVER;
+    sampler_ci.minLod = 1.0;
+    sampler_ci.maxLod = 1.0;
+    sampler_ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
+    sampler_ci.unnormalizedCoordinates = VK_FALSE;
+    VkSampler sampler;
+
+    err = vkCreateSampler(m_device->device(), &sampler_ci, NULL, &sampler);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding layout_binding;
+    layout_binding.binding = 0;
+    layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    layout_binding.descriptorCount = 1;
+    layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    layout_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &layout_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    VkDescriptorSet descriptor_set;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageView view;
+    VkImageViewCreateInfo ivci = {};
+    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    ivci.image = image.handle();
+    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
+    ivci.subresourceRange.layerCount = 1;
+    ivci.subresourceRange.baseMipLevel = 0;
+    ivci.subresourceRange.levelCount = 1;
+    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+    err = vkCreateImageView(m_device->device(), &ivci, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorImageInfo image_info{};
+    image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    image_info.imageView = view;
+    image_info.sampler = sampler;
+
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptor_set;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+    descriptor_write.pImageInfo = &image_info;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    // Create PSO to use the sampler
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex { \n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(set=0, binding=0) uniform sampler2D s;\n"
+                           "layout(location=0) out vec4 x;\n"
+                           "void main(){\n"
+                           "   x = texture(s, vec2(1));\n"
+                           "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete image view 0x");
+
+    BeginCommandBuffer();
+    // Bind pipeline to cmd buffer
+    vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
+                            &descriptor_set, 0, nullptr);
+    Draw(1, 0, 0, 0);
+    EndCommandBuffer();
+    // Submit cmd buffer then destroy sampler
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    // Submit cmd buffer and then destroy imageView while in-flight
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    vkDestroyImageView(m_device->device(), view, nullptr);
+    m_errorMonitor->VerifyFound();
+    vkQueueWaitIdle(m_device->m_queue);
+    // Now we can actually destroy imageView
+    vkDestroyImageView(m_device->device(), view, NULL);
+    vkDestroySampler(m_device->device(), sampler, nullptr);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+TEST_F(VkLayerTest, BufferViewInUseDestroyedSignaled) {
+    TEST_DESCRIPTION("Delete in-use bufferView.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorPoolSize ds_type_count;
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    ds_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    VkResult err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetLayoutBinding layout_binding;
+    layout_binding.binding = 0;
+    layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    layout_binding.descriptorCount = 1;
+    layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    layout_binding.pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.bindingCount = 1;
+    ds_layout_ci.pBindings = &layout_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    VkDescriptorSet descriptor_set;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pNext = NULL;
+    pipeline_layout_ci.setLayoutCount = 1;
+    pipeline_layout_ci.pSetLayouts = &ds_layout;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBuffer buffer;
+    uint32_t queue_family_index = 0;
+    VkBufferCreateInfo buffer_create_info = {};
+    buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buffer_create_info.size = 1024;
+    buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+    buffer_create_info.queueFamilyIndexCount = 1;
+    buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+    err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    VkMemoryRequirements memory_reqs;
+    VkDeviceMemory buffer_memory;
+
+    VkMemoryAllocateInfo memory_info = {};
+    memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    memory_info.allocationSize = 0;
+    memory_info.memoryTypeIndex = 0;
+
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+    memory_info.allocationSize = memory_reqs.size;
+    bool pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+    ASSERT_TRUE(pass);
+
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkBufferView view;
+    VkBufferViewCreateInfo bvci = {};
+    bvci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+    bvci.buffer = buffer;
+    bvci.format = VK_FORMAT_R8_UNORM;
+    bvci.range = VK_WHOLE_SIZE;
+
+    err = vkCreateBufferView(m_device->device(), &bvci, NULL, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstSet = descriptor_set;
+    descriptor_write.dstBinding = 0;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+    descriptor_write.pTexelBufferView = &view;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex { \n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(set=0, binding=0, r8) uniform imageBuffer s;\n"
+                           "layout(location=0) out vec4 x;\n"
+                           "void main(){\n"
+                           "   x = imageLoad(s, 0);\n"
+                           "}\n";
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Cannot delete buffer view 0x");
+
+    BeginCommandBuffer();
+    VkViewport viewport = {0, 0, 16, 16, 0, 1};
+    vkCmdSetViewport(m_commandBuffer->handle(), 0, 1, &viewport);
+    VkRect2D scissor = {{0, 0}, {16, 16}};
+    vkCmdSetScissor(m_commandBuffer->handle(), 0, 1, &scissor);
+    // Bind pipeline to cmd buffer
+    vkCmdBindPipeline(m_commandBuffer->handle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipe.handle());
+    vkCmdBindDescriptorSets(m_commandBuffer->GetBufferHandle(), VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1,
+                            &descriptor_set, 0, nullptr);
+    Draw(1, 0, 0, 0);
+    EndCommandBuffer();
+
+    VkSubmitInfo submit_info = {};
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &m_commandBuffer->handle();
+    // Submit cmd buffer and then destroy bufferView while in-flight
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+
+    vkDestroyBufferView(m_device->device(), view, nullptr);
+    m_errorMonitor->VerifyFound();
+    vkQueueWaitIdle(m_device->m_queue);
+    // Now we can actually destroy bufferView
+    vkDestroyBufferView(m_device->device(), view, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
 TEST_F(VkLayerTest, SamplerInUseDestroyedSignaled) {
     TEST_DESCRIPTION("Delete in-use sampler.");
 
@@ -12801,7 +10923,7 @@
 
     VkDescriptorSetLayoutBinding layout_binding;
     layout_binding.binding = 0;
-    layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+    layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
     layout_binding.descriptorCount = 1;
     layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
     layout_binding.pImmutableSamplers = NULL;
@@ -13039,10 +11161,15 @@
     vkBeginCommandBuffer(sec_cb, &cbbi);
     vkEndCommandBuffer(sec_cb);
 
-    BeginCommandBuffer();
+    VkCommandBufferBeginInfo cbbi2 = {
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
+        0, nullptr
+    };
+    vkBeginCommandBuffer(m_commandBuffer->GetBufferHandle(), &cbbi2);
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
 
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
-                                         " that is not the same as the primaryCB's current active framebuffer ");
+                                         " that is not the same as the primary command buffer's current active framebuffer ");
     vkCmdExecuteCommands(m_commandBuffer->GetBufferHandle(), 1, &sec_cb);
     m_errorMonitor->VerifyFound();
     // Cleanup
@@ -13065,7 +11192,7 @@
                                                                             "enabled, logicOpEnable must be "
                                                                             "VK_FALSE");
     } else {
-        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, ", logicOp must be a valid VkLogicOp value");
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "pColorBlendState->logicOp (16)");
     }
     // Create a pipeline using logicOp
     VkResult err;
@@ -13085,9 +11212,6 @@
     vp_state_ci.scissorCount = 1;
     VkRect2D scissors = {}; // Dummy scissors to point to
     vp_state_ci.pScissors = &scissors;
-    // No dynamic state
-    VkPipelineDynamicStateCreateInfo dyn_state_ci = {};
-    dyn_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
 
     VkPipelineShaderStageCreateInfo shaderStages[2];
     memset(&shaderStages, 0, 2 * sizeof(VkPipelineShaderStageCreateInfo));
@@ -13106,6 +11230,7 @@
 
     VkPipelineRasterizationStateCreateInfo rs_ci = {};
     rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+    rs_ci.lineWidth = 1.0f;
 
     VkPipelineColorBlendAttachmentState att = {};
     att.blendEnable = VK_FALSE;
@@ -13119,6 +11244,10 @@
     cb_ci.attachmentCount = 1;
     cb_ci.pAttachments = &att;
 
+    VkPipelineMultisampleStateCreateInfo ms_ci = {};
+    ms_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
+    ms_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+
     VkGraphicsPipelineCreateInfo gp_ci = {};
     gp_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
     gp_ci.stageCount = 2;
@@ -13128,7 +11257,7 @@
     gp_ci.pViewportState = &vp_state_ci;
     gp_ci.pRasterizationState = &rs_ci;
     gp_ci.pColorBlendState = &cb_ci;
-    gp_ci.pDynamicState = &dyn_state_ci;
+    gp_ci.pMultisampleState = &ms_ci;
     gp_ci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
     gp_ci.layout = pipeline_layout;
     gp_ci.renderPass = renderPass();
@@ -13146,7 +11275,6 @@
     if (VK_SUCCESS == err) {
         vkDestroyPipeline(m_device->device(), pipeline, NULL);
     }
-    m_errorMonitor->VerifyFound();
     vkDestroyPipelineCache(m_device->device(), pipelineCache, NULL);
     vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
 }
@@ -13360,6 +11488,479 @@
     m_errorMonitor->VerifyFound();
 }
 
+TEST_F(VkLayerTest, CreatePipelineCheckShaderBadSpecialization) {
+    TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *bad_specialization_message =
+            "Specialization entry 0 (for constant id 0) references memory outside provided specialization data ";
+
+    char const *vsSource =
+            "#version 450\n"
+            "\n"
+            "out gl_PerVertex {\n"
+            "    vec4 gl_Position;\n"
+            "};\n"
+            "void main(){\n"
+            "   gl_Position = vec4(1);\n"
+            "}\n";
+
+    char const *fsSource =
+            "#version 450\n"
+            "\n"
+            "layout (constant_id = 0) const float r = 0.0f;\n"
+            "layout(location = 0) out vec4 uFragColor;\n"
+            "void main(){\n"
+            "   uFragColor = vec4(r,1,0,1);\n"
+            "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    VkPipelineViewportStateCreateInfo vp_state_create_info = {};
+    vp_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+    vp_state_create_info.viewportCount = 1;
+    VkViewport viewport = {};
+    vp_state_create_info.pViewports = &viewport;
+    vp_state_create_info.scissorCount = 1;
+    VkRect2D scissors = {};
+    vp_state_create_info.pScissors = &scissors;
+
+    VkDynamicState scissor_state = VK_DYNAMIC_STATE_SCISSOR;
+
+    VkPipelineDynamicStateCreateInfo pipeline_dynamic_state_create_info = {};
+    pipeline_dynamic_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
+    pipeline_dynamic_state_create_info.dynamicStateCount = 1;
+    pipeline_dynamic_state_create_info.pDynamicStates = &scissor_state;
+
+    VkPipelineShaderStageCreateInfo shader_stage_create_info[2] = {
+        vs.GetStageCreateInfo(),
+        fs.GetStageCreateInfo()
+    };
+
+    VkPipelineVertexInputStateCreateInfo vertex_input_create_info = {};
+    vertex_input_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
+
+    VkPipelineInputAssemblyStateCreateInfo input_assembly_create_info = {};
+    input_assembly_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
+    input_assembly_create_info.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+    VkPipelineRasterizationStateCreateInfo rasterization_state_create_info = {};
+    rasterization_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+    rasterization_state_create_info.pNext = nullptr;
+    rasterization_state_create_info.lineWidth = 1.0f;
+    rasterization_state_create_info.rasterizerDiscardEnable = true;
+
+    VkPipelineColorBlendAttachmentState color_blend_attachment_state = {};
+    color_blend_attachment_state.blendEnable = VK_FALSE;
+    color_blend_attachment_state.colorWriteMask = 0xf;
+
+    VkPipelineColorBlendStateCreateInfo color_blend_state_create_info = {};
+    color_blend_state_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
+    color_blend_state_create_info.attachmentCount = 1;
+    color_blend_state_create_info.pAttachments = &color_blend_attachment_state;
+
+    VkGraphicsPipelineCreateInfo graphicspipe_create_info = {};
+    graphicspipe_create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
+    graphicspipe_create_info.stageCount = 2;
+    graphicspipe_create_info.pStages = shader_stage_create_info;
+    graphicspipe_create_info.pVertexInputState = &vertex_input_create_info;
+    graphicspipe_create_info.pInputAssemblyState = &input_assembly_create_info;
+    graphicspipe_create_info.pViewportState = &vp_state_create_info;
+    graphicspipe_create_info.pRasterizationState = &rasterization_state_create_info;
+    graphicspipe_create_info.pColorBlendState = &color_blend_state_create_info;
+    graphicspipe_create_info.pDynamicState = &pipeline_dynamic_state_create_info;
+    graphicspipe_create_info.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
+    graphicspipe_create_info.layout = pipeline_layout;
+    graphicspipe_create_info.renderPass = renderPass();
+
+    VkPipelineCacheCreateInfo pipeline_cache_create_info = {};
+    pipeline_cache_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
+
+    VkPipelineCache pipelineCache;
+    ASSERT_VK_SUCCESS(vkCreatePipelineCache(m_device->device(), &pipeline_cache_create_info, nullptr, &pipelineCache));
+
+    // This structure maps constant ids to data locations.
+    const VkSpecializationMapEntry entry =
+        // id,  offset,                size
+        {0, 4, sizeof(uint32_t)};  // Challenge core validation by using a bogus offset.
+
+    uint32_t data = 1;
+
+    // Set up the info describing spec map and data
+    const VkSpecializationInfo specialization_info = {
+        1,
+        &entry,
+        1 * sizeof(float),
+        &data,
+    };
+    shader_stage_create_info[0].pSpecializationInfo = &specialization_info;
+
+    VkPipeline pipeline;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_specialization_message);
+    vkCreateGraphicsPipelines(m_device->device(), pipelineCache, 1, &graphicspipe_create_info, nullptr, &pipeline);
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineCache(m_device->device(), pipelineCache, nullptr);
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
+}
+
+TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorTypeMismatch) {
+    TEST_DESCRIPTION("Challenge core_validation with shader validation issues related to vkCreateGraphicsPipelines.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *descriptor_type_mismatch_message = "Type mismatch on descriptor slot 0.0 (used as type ";
+
+    VkDescriptorPoolSize descriptor_pool_type_count[2] = {};
+    descriptor_pool_type_count[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    descriptor_pool_type_count[0].descriptorCount = 1;
+    descriptor_pool_type_count[1].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+    descriptor_pool_type_count[1].descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
+    descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    descriptor_pool_create_info.maxSets = 1;
+    descriptor_pool_create_info.poolSizeCount = 2;
+    descriptor_pool_create_info.pPoolSizes = descriptor_pool_type_count;
+    descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+
+    VkDescriptorPool descriptorset_pool;
+    ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
+
+    VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
+    descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
+    descriptorset_layout_binding.descriptorCount = 1;
+    descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_ALL;
+
+    VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
+    descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    descriptorset_layout_create_info.bindingCount = 1;
+    descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
+
+    VkDescriptorSetLayout descriptorset_layout;
+    ASSERT_VK_SUCCESS(vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info, nullptr, &descriptorset_layout));
+
+    VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
+    descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    descriptorset_allocate_info.descriptorSetCount = 1;
+    descriptorset_allocate_info.descriptorPool = descriptorset_pool;
+    descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
+    VkDescriptorSet descriptorset;
+    ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
+
+    // Challenge core_validation with a non uniform buffer type.
+    VkBufferTest storage_buffer_test(m_device, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
+
+    char const *vsSource =
+            "#version 450\n"
+            "\n"
+            "layout (std140, set = 0, binding = 0) uniform buf {\n"
+            "    mat4 mvp;\n"
+            "} ubuf;\n"
+            "out gl_PerVertex {\n"
+            "    vec4 gl_Position;\n"
+            "};\n"
+            "void main(){\n"
+            "   gl_Position = ubuf.mvp * vec4(1);\n"
+            "}\n";
+
+    char const *fsSource =
+            "#version 450\n"
+            "\n"
+            "layout(location = 0) out vec4 uFragColor;\n"
+            "void main(){\n"
+            "   uFragColor = vec4(0,1,0,1);\n"
+            "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_create_info.setLayoutCount = 1;
+    pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
+
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_type_mismatch_message);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
+    vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
+}
+
+TEST_F(VkLayerTest, CreatePipelineCheckShaderDescriptorNotAccessible) {
+    TEST_DESCRIPTION(
+        "Create a pipeline in which a descriptor used by a shader stage does not include that stage in its stageFlags.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *descriptor_not_accessible_message = "Shader uses descriptor slot 0.0 (used as type ";
+
+    VkDescriptorPoolSize descriptor_pool_type_count = {};
+    descriptor_pool_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    descriptor_pool_type_count.descriptorCount = 1;
+
+    VkDescriptorPoolCreateInfo descriptor_pool_create_info = {};
+    descriptor_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    descriptor_pool_create_info.maxSets = 1;
+    descriptor_pool_create_info.poolSizeCount = 1;
+    descriptor_pool_create_info.pPoolSizes = &descriptor_pool_type_count;
+    descriptor_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
+
+    VkDescriptorPool descriptorset_pool;
+    ASSERT_VK_SUCCESS(vkCreateDescriptorPool(m_device->device(), &descriptor_pool_create_info, nullptr, &descriptorset_pool));
+
+    VkDescriptorSetLayoutBinding descriptorset_layout_binding = {};
+    descriptorset_layout_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    descriptorset_layout_binding.descriptorCount = 1;
+    // Intentionally make the uniform buffer inaccessible to the vertex shader to challenge core_validation
+    descriptorset_layout_binding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+
+    VkDescriptorSetLayoutCreateInfo descriptorset_layout_create_info = {};
+    descriptorset_layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    descriptorset_layout_create_info.bindingCount = 1;
+    descriptorset_layout_create_info.pBindings = &descriptorset_layout_binding;
+
+    VkDescriptorSetLayout descriptorset_layout;
+    ASSERT_VK_SUCCESS(vkCreateDescriptorSetLayout(m_device->device(), &descriptorset_layout_create_info,
+                                                  nullptr, &descriptorset_layout));
+
+    VkDescriptorSetAllocateInfo descriptorset_allocate_info = {};
+    descriptorset_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    descriptorset_allocate_info.descriptorSetCount = 1;
+    descriptorset_allocate_info.descriptorPool = descriptorset_pool;
+    descriptorset_allocate_info.pSetLayouts = &descriptorset_layout;
+    VkDescriptorSet descriptorset;
+    ASSERT_VK_SUCCESS(vkAllocateDescriptorSets(m_device->device(), &descriptorset_allocate_info, &descriptorset));
+
+    VkBufferTest buffer_test(m_device, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
+
+    char const *vsSource =
+            "#version 450\n"
+            "\n"
+            "layout (std140, set = 0, binding = 0) uniform buf {\n"
+            "    mat4 mvp;\n"
+            "} ubuf;\n"
+            "out gl_PerVertex {\n"
+            "    vec4 gl_Position;\n"
+            "};\n"
+            "void main(){\n"
+            "   gl_Position = ubuf.mvp * vec4(1);\n"
+            "}\n";
+
+    char const *fsSource =
+            "#version 450\n"
+            "\n"
+            "layout(location = 0) out vec4 uFragColor;\n"
+            "void main(){\n"
+            "   uFragColor = vec4(0,1,0,1);\n"
+            "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_create_info.setLayoutCount = 1;
+    pipeline_layout_create_info.pSetLayouts = &descriptorset_layout;
+
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, descriptor_not_accessible_message);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
+    vkDestroyDescriptorPool(m_device->device(), descriptorset_pool, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), descriptorset_layout, nullptr);
+}
+
+TEST_F(VkLayerTest, CreatePipelineCheckShaderPushConstantNotAccessible) {
+    TEST_DESCRIPTION("Create a graphics pipleine in which a push constant range containing a push constant block member is not "
+                     "accessible from the current shader stage.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *push_constant_not_accessible_message =
+            "Push constant range covering variable starting at offset 0 not accessible from stage VK_SHADER_STAGE_VERTEX_BIT";
+
+    char const *vsSource =
+            "#version 450\n"
+            "\n"
+            "layout(push_constant, std430) uniform foo { float x; } consts;\n"
+            "out gl_PerVertex {\n"
+            "    vec4 gl_Position;\n"
+            "};\n"
+            "void main(){\n"
+            "   gl_Position = vec4(consts.x);\n"
+            "}\n";
+
+    char const *fsSource =
+            "#version 450\n"
+            "\n"
+            "layout(location = 0) out vec4 uFragColor;\n"
+            "void main(){\n"
+            "   uFragColor = vec4(0,1,0,1);\n"
+            "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+
+    // Set up a push constant range
+    VkPushConstantRange push_constant_ranges = {};
+    // Set to the wrong stage to challenge core_validation
+    push_constant_ranges.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    push_constant_ranges.size = 4;
+
+    pipeline_layout_create_info.pPushConstantRanges = &push_constant_ranges;
+    pipeline_layout_create_info.pushConstantRangeCount = 1;
+
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, push_constant_not_accessible_message);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
+}
+
+TEST_F(VkLayerTest, CreatePipelineCheckShaderNotEnabled) {
+    TEST_DESCRIPTION(
+        "Create a graphics pipeline in which a capability declared by the shader requires a feature not enabled on the device.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *feature_not_enabled_message =
+            "Shader requires VkPhysicalDeviceFeatures::shaderFloat64 but is not enabled on the device";
+
+    // Some awkward steps are required to test with custom device features.
+    std::vector<const char *> device_extension_names;
+    auto features = m_device->phy().features();
+    // Disable support for 64 bit floats
+    features.shaderFloat64 = false;
+    // The sacrificial device object
+    VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
+
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex {\n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(location=0) out vec4 color;\n"
+                           "void main(){\n"
+                           "   dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
+                           "   color = vec4(green);\n"
+                           "}\n";
+
+    VkShaderObj vs(&test_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(&test_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkRenderpassObj render_pass(&test_device);
+
+    VkPipelineObj pipe(&test_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(test_device.device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, feature_not_enabled_message);
+    pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(test_device.device(), pipeline_layout, nullptr);
+}
+
+TEST_F(VkLayerTest, CreatePipelineCheckShaderBadCapability) {
+    TEST_DESCRIPTION("Create a graphics pipeline in which a capability declared by the shader is not supported by Vulkan shaders.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    const char *bad_capability_message = "Shader declares capability 53, not supported in Vulkan.";
+
+    char const *vsSource = "#version 450\n"
+                           "\n"
+                           "out gl_PerVertex {\n"
+                           "    vec4 gl_Position;\n"
+                           "};\n"
+                           "layout(xfb_buffer = 1) out;"
+                           "void main(){\n"
+                           "   gl_Position = vec4(1);\n"
+                           "}\n";
+    char const *fsSource = "#version 450\n"
+                           "\n"
+                           "layout(location=0) out vec4 color;\n"
+                           "void main(){\n"
+                           "   dvec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
+                           "   color = vec4(green);\n"
+                           "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_create_info = {};
+    pipeline_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    VkPipelineLayout pipeline_layout;
+    ASSERT_VK_SUCCESS(vkCreatePipelineLayout(m_device->device(), &pipeline_layout_create_info, nullptr, &pipeline_layout));
+
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, bad_capability_message);
+    pipe.CreateVKPipeline(pipeline_layout, renderPass());
+    m_errorMonitor->VerifyFound();
+
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, nullptr);
+}
+
 TEST_F(VkLayerTest, CreatePipelineFragmentInputNotProvided) {
     TEST_DESCRIPTION("Test that an error is produced for a fragment shader input "
                      "which is not present in the outputs of the previous stage");
@@ -13446,7 +12047,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchArraySize) {
     TEST_DESCRIPTION("Test that an error is produced for mismatched array sizes "
-                     "across the VS->FS interface");
+                     "across the vertex->fragment shader interface");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0.0: 'ptr to "
                                                                         "output arr[2] of float32' vs 'ptr to "
                                                                         "input arr[3] of float32'");
@@ -13489,9 +12090,10 @@
     m_errorMonitor->VerifyFound();
 }
 
+
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
-                     "the VS->FS interface");
+                     "the vertex->fragment shader interface");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
@@ -13534,7 +12136,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineVsFsTypeMismatchInBlock) {
     TEST_DESCRIPTION("Test that an error is produced for mismatched types across "
-                     "the VS->FS interface, when the variable is contained within "
+                     "the vertex->fragment shader interface, when the variable is contained within "
                      "an interface block");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Type mismatch on location 0");
 
@@ -13578,7 +12180,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByLocation) {
     TEST_DESCRIPTION("Test that an error is produced for location mismatches across "
-                     "the VS->FS interface; This should manifest as a not-written/not-consumed "
+                     "the vertex->fragment shader interface; This should manifest as a not-written/not-consumed "
                      "pair, but flushes out broken walking of the interfaces");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.0 which is not written by vertex shader");
 
@@ -13622,7 +12224,7 @@
 
 TEST_F(VkLayerTest, CreatePipelineVsFsMismatchByComponent) {
     TEST_DESCRIPTION("Test that an error is produced for component mismatches across the "
-                     "VS->FS interface. It's not enough to have the same set of locations in "
+                     "vertex->fragment shader interface. It's not enough to have the same set of locations in "
                      "use; matching is defined in terms of spirv variables.");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0.1 which is not written by vertex shader");
 
@@ -13667,7 +12269,7 @@
 TEST_F(VkLayerTest, CreatePipelineAttribNotConsumed) {
     TEST_DESCRIPTION("Test that a warning is produced for a vertex attribute which is "
                      "not consumed by the vertex shader");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -13717,7 +12319,7 @@
 TEST_F(VkLayerTest, CreatePipelineAttribLocationMismatch) {
     TEST_DESCRIPTION("Test that a warning is produced for a location mismatch on "
                      "vertex attributes. This flushes out bad behavior in the interface walker");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by VS");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, "location 0 not consumed by vertex shader");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -13766,9 +12368,9 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineAttribNotProvided) {
-    TEST_DESCRIPTION("Test that an error is produced for a VS input which is not "
+    TEST_DESCRIPTION("Test that an error is produced for a vertex shader input which is not "
                      "provided by a vertex attribute");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "VS consumes input at location 0 but not provided");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Vertex shader consumes input at location 0 but not provided");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -13809,8 +12411,8 @@
 TEST_F(VkLayerTest, CreatePipelineAttribTypeMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the "
                      "fundamental type (float/int/uint) of an attribute and the "
-                     "VS input that consumes it");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match VS input type");
+                     "vertex shader input that consumes it");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "location 0 does not match vertex shader input type");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
     ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
@@ -13888,7 +12490,7 @@
     VkPipelineObj pipe(m_device);
     pipe.AddColorAttachment();
     pipe.AddShader(&vs);
-    pipe.AddShader(&vs);
+    pipe.AddShader(&vs);        // intentionally duplicate vertex shader attachment
     pipe.AddShader(&fs);
 
     VkDescriptorSetObj descriptorSet(m_device);
@@ -13900,174 +12502,6 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, CreatePipelineAttribMatrixType) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
-                     "as vertex attributes");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    VkVertexInputBindingDescription input_binding;
-    memset(&input_binding, 0, sizeof(input_binding));
-
-    VkVertexInputAttributeDescription input_attribs[2];
-    memset(input_attribs, 0, sizeof(input_attribs));
-
-    for (int i = 0; i < 2; i++) {
-        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
-        input_attribs[i].location = i;
-    }
-
-    char const *vsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) in mat2x4 x;\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "   gl_Position = x[0] + x[1];\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    pipe.AddVertexInputBindings(&input_binding, 1);
-    pipe.AddVertexInputAttribs(input_attribs, 2);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    /* expect success */
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, CreatePipelineAttribArrayType) {
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    VkVertexInputBindingDescription input_binding;
-    memset(&input_binding, 0, sizeof(input_binding));
-
-    VkVertexInputAttributeDescription input_attribs[2];
-    memset(input_attribs, 0, sizeof(input_attribs));
-
-    for (int i = 0; i < 2; i++) {
-        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
-        input_attribs[i].location = i;
-    }
-
-    char const *vsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) in vec4 x[2];\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "   gl_Position = x[0] + x[1];\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    pipe.AddVertexInputBindings(&input_binding, 1);
-    pipe.AddVertexInputAttribs(input_attribs, 2);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, CreatePipelineAttribComponents) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
-                     "through multiple VS inputs, each consuming a different subset of the "
-                     "components.");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    VkVertexInputBindingDescription input_binding;
-    memset(&input_binding, 0, sizeof(input_binding));
-
-    VkVertexInputAttributeDescription input_attribs[3];
-    memset(input_attribs, 0, sizeof(input_attribs));
-
-    for (int i = 0; i < 3; i++) {
-        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
-        input_attribs[i].location = i;
-    }
-
-    char const *vsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) in vec4 x;\n"
-                           "layout(location=1) in vec3 y1;\n"
-                           "layout(location=1, component=3) in float y2;\n"
-                           "layout(location=2) in vec4 z;\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "   gl_Position = x + vec4(y1, y2) + z;\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    pipe.AddVertexInputBindings(&input_binding, 1);
-    pipe.AddVertexInputAttribs(input_attribs, 3);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, CreatePipelineMissingEntrypoint) {
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
                                          "No entrypoint found named `foo`");
@@ -14106,43 +12540,6 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, CreatePipelineSimplePositive) {
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    char const *vsSource = "#version 450\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "   gl_Position = vec4(0);\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, CreatePipelineDepthStencilRequired) {
     m_errorMonitor->SetDesiredFailureMsg(
         VK_DEBUG_REPORT_ERROR_BIT_EXT,
@@ -14209,176 +12606,6 @@
     vkDestroyRenderPass(m_device->device(), rp, nullptr);
 }
 
-TEST_F(VkLayerTest, CreatePipelineRelaxedTypeMatch) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
-                     "set out in 14.1.3: fundamental type must match, and producer side must "
-                     "have at least as many components");
-    m_errorMonitor->ExpectSuccess();
-
-    // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    char const *vsSource = "#version 450\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "layout(location=0) out vec3 x;\n"
-                           "layout(location=1) out ivec3 y;\n"
-                           "layout(location=2) out vec3 z;\n"
-                           "void main(){\n"
-                           "   gl_Position = vec4(0);\n"
-                           "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "layout(location=0) in float x;\n"
-                           "layout(location=1) flat in int y;\n"
-                           "layout(location=2) in vec2 z;\n"
-                           "void main(){\n"
-                           "   color = vec4(1 + x + y + z.x);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    VkResult err = VK_SUCCESS;
-    err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-    ASSERT_VK_SUCCESS(err);
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, CreatePipelineTessPerVertex) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
-                     "passed between the TCS and TES stages");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    if (!m_device->phy().features().tessellationShader) {
-        printf("Device does not support tessellation shaders; skipped.\n");
-        return;
-    }
-
-    char const *vsSource = "#version 450\n"
-                           "void main(){}\n";
-    char const *tcsSource = "#version 450\n"
-                            "layout(location=0) out int x[];\n"
-                            "layout(vertices=3) out;\n"
-                            "void main(){\n"
-                            "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
-                            "   gl_TessLevelInner[0] = 1;\n"
-                            "   x[gl_InvocationID] = gl_InvocationID;\n"
-                            "}\n";
-    char const *tesSource = "#version 450\n"
-                            "layout(triangles, equal_spacing, cw) in;\n"
-                            "layout(location=0) in int x[];\n"
-                            "out gl_PerVertex { vec4 gl_Position; };\n"
-                            "void main(){\n"
-                            "   gl_Position.xyz = gl_TessCoord;\n"
-                            "   gl_Position.w = x[0] + x[1] + x[2];\n"
-                            "}\n";
-    char const *fsSource = "#version 450\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
-    VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineInputAssemblyStateCreateInfo iasci{VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
-                                                 VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE};
-
-    VkPipelineTessellationStateCreateInfo tsci{VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3};
-
-    VkPipelineObj pipe(m_device);
-    pipe.SetInputAssembly(&iasci);
-    pipe.SetTessellation(&tsci);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&tcs);
-    pipe.AddShader(&tes);
-    pipe.AddShader(&fs);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
-TEST_F(VkLayerTest, CreatePipelineGeometryInputBlockPositive) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
-                     "interface block passed into the geometry shader. This "
-                     "is interesting because the 'extra' array level is not "
-                     "present on the member type, but on the block instance.");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    if (!m_device->phy().features().geometryShader) {
-        printf("Device does not support geometry shaders; skipped.\n");
-        return;
-    }
-
-    char const *vsSource = "#version 450\n"
-                           "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
-                           "void main(){\n"
-                           "   vs_out.x = vec4(1);\n"
-                           "}\n";
-    char const *gsSource = "#version 450\n"
-                           "layout(triangles) in;\n"
-                           "layout(triangle_strip, max_vertices=3) out;\n"
-                           "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
-                           "out gl_PerVertex { vec4 gl_Position; };\n"
-                           "void main() {\n"
-                           "   gl_Position = gs_in[0].x;\n"
-                           "   EmitVertex();\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&gs);
-    pipe.AddShader(&fs);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, CreatePipelineTessPatchDecorationMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for a variable output from "
                      "the TCS without the patch decoration, but consumed in the TES "
@@ -14499,78 +12726,10 @@
     m_errorMonitor->VerifyFound();
 }
 
-TEST_F(VkLayerTest, CreatePipeline64BitAttributesPositive) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
-                     "attributes. This is interesting because they consume multiple "
-                     "locations.");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    if (!m_device->phy().features().shaderFloat64) {
-        printf("Device does not support 64bit vertex attributes; skipped.\n");
-        return;
-    }
-
-    VkVertexInputBindingDescription input_bindings[1];
-    memset(input_bindings, 0, sizeof(input_bindings));
-
-    VkVertexInputAttributeDescription input_attribs[4];
-    memset(input_attribs, 0, sizeof(input_attribs));
-    input_attribs[0].location = 0;
-    input_attribs[0].offset = 0;
-    input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
-    input_attribs[1].location = 2;
-    input_attribs[1].offset = 32;
-    input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
-    input_attribs[2].location = 4;
-    input_attribs[2].offset = 64;
-    input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
-    input_attribs[3].location = 6;
-    input_attribs[3].offset = 96;
-    input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
-
-    char const *vsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) in dmat4 x;\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "   gl_Position = vec4(x[0][0]);\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main(){\n"
-                           "   color = vec4(1);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddColorAttachment();
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-
-    pipe.AddVertexInputBindings(input_bindings, 1);
-    pipe.AddVertexInputAttribs(input_attribs, 4);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.AppendDummy();
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
-
-    m_errorMonitor->VerifyNotFound();
-}
-
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotWritten) {
-    TEST_DESCRIPTION("Test that an error is produced for a FS which does not "
+    TEST_DESCRIPTION("Test that an error is produced for a fragment shader which does not "
                      "provide an output for one of the pipeline's color attachments");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by FS");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "Attachment 0 not written by fragment shader");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -14608,10 +12767,10 @@
 }
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputNotConsumed) {
-    TEST_DESCRIPTION("Test that a warning is produced for a FS which provides a spurious "
+    TEST_DESCRIPTION("Test that a warning is produced for a fragment shader which provides a spurious "
                      "output with no matching attachment");
     m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT,
-                                         "FS writes to output location 1 with no matching attachment");
+                                         "fragment shader writes to output location 1 with no matching attachment");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -14655,8 +12814,8 @@
 
 TEST_F(VkLayerTest, CreatePipelineFragmentOutputTypeMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for a mismatch between the fundamental "
-                     "type of an FS output variable, and the format of the corresponding attachment");
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match FS output type");
+                     "type of an fragment shader output variable, and the format of the corresponding attachment");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "does not match fragment shader output type");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -14833,79 +12992,6 @@
     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
 }
 
-TEST_F(VkLayerTest, CreatePipelineInputAttachmentPositive) {
-    TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    char const *vsSource = "#version 450\n"
-                           "\n"
-                           "out gl_PerVertex {\n"
-                           "    vec4 gl_Position;\n"
-                           "};\n"
-                           "void main(){\n"
-                           "    gl_Position = vec4(1);\n"
-                           "}\n";
-    char const *fsSource = "#version 450\n"
-                           "\n"
-                           "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
-                           "layout(location=0) out vec4 color;\n"
-                           "void main() {\n"
-                           "   color = subpassLoad(x);\n"
-                           "}\n";
-
-    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
-    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
-
-    VkPipelineObj pipe(m_device);
-    pipe.AddShader(&vs);
-    pipe.AddShader(&fs);
-    pipe.AddColorAttachment();
-    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
-
-    VkDescriptorSetLayoutBinding dslb = {0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr};
-    VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb};
-    VkDescriptorSetLayout dsl;
-    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
-    ASSERT_VK_SUCCESS(err);
-
-    VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
-    VkPipelineLayout pl;
-    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
-    ASSERT_VK_SUCCESS(err);
-
-    VkAttachmentDescription descs[2] = {
-        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
-         VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL},
-        {0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
-         VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL},
-    };
-    VkAttachmentReference color = {
-        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
-    };
-    VkAttachmentReference input = {
-        1, VK_IMAGE_LAYOUT_GENERAL,
-    };
-
-    VkSubpassDescription sd = {0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr};
-
-    VkRenderPassCreateInfo rpci = {VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr};
-    VkRenderPass rp;
-    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
-    ASSERT_VK_SUCCESS(err);
-
-    // should be OK. would go wrong here if it's going to...
-    pipe.CreateVKPipeline(pl, rp);
-
-    m_errorMonitor->VerifyNotFound();
-
-    vkDestroyRenderPass(m_device->device(), rp, nullptr);
-    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
-    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
-}
-
 TEST_F(VkLayerTest, CreatePipelineInputAttachmentTypeMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for a shader consuming an input attachment "
                      "with a format having a different fundamental type");
@@ -15073,47 +13159,6 @@
     }
 }
 
-TEST_F(VkLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
-                     "descriptor-backed resource which is not provided, but the shader does not "
-                     "statically use it. This is interesting because it requires compute pipelines "
-                     "to have a proper descriptor use walk, which they didn't for some time.");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    char const *csSource = "#version 450\n"
-                           "\n"
-                           "layout(local_size_x=1) in;\n"
-                           "layout(set=0, binding=0) buffer block { vec4 x; };\n"
-                           "void main(){\n"
-                           "   // x is not used.\n"
-                           "}\n";
-
-    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
-
-    VkDescriptorSetObj descriptorSet(m_device);
-    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
-
-    VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
-                                        nullptr,
-                                        0,
-                                        {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
-                                         VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
-                                        descriptorSet.GetPipelineLayout(),
-                                        VK_NULL_HANDLE,
-                                        -1};
-
-    VkPipeline pipe;
-    VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
-
-    m_errorMonitor->VerifyNotFound();
-
-    if (err == VK_SUCCESS) {
-        vkDestroyPipeline(m_device->device(), pipe, nullptr);
-    }
-}
-
 TEST_F(VkLayerTest, CreateComputePipelineDescriptorTypeMismatch) {
     TEST_DESCRIPTION("Test that an error is produced for a pipeline consuming a "
                      "descriptor-backed resource of a mismatched type");
@@ -15164,171 +13209,6 @@
     vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
 }
 
-TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
-                     "sampler portion of a combined image + sampler");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkDescriptorSetLayoutBinding bindings[] = {
-        {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-        {1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-        {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-    };
-    VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
-    VkDescriptorSetLayout dsl;
-    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
-    ASSERT_VK_SUCCESS(err);
-
-    VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
-    VkPipelineLayout pl;
-    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
-    ASSERT_VK_SUCCESS(err);
-
-    char const *csSource = "#version 450\n"
-                           "\n"
-                           "layout(local_size_x=1) in;\n"
-                           "layout(set=0, binding=0) uniform sampler s;\n"
-                           "layout(set=0, binding=1) uniform texture2D t;\n"
-                           "layout(set=0, binding=2) buffer block { vec4 x; };\n"
-                           "void main() {\n"
-                           "   x = texture(sampler2D(t, s), vec2(0));\n"
-                           "}\n";
-    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
-
-    VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
-                                        nullptr,
-                                        0,
-                                        {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
-                                         VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
-                                        pl,
-                                        VK_NULL_HANDLE,
-                                        -1};
-
-    VkPipeline pipe;
-    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
-
-    m_errorMonitor->VerifyNotFound();
-
-    if (err == VK_SUCCESS) {
-        vkDestroyPipeline(m_device->device(), pipe, nullptr);
-    }
-
-    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
-    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
-}
-
-TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
-                     "image portion of a combined image + sampler");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkDescriptorSetLayoutBinding bindings[] = {
-        {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-        {1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-        {2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-    };
-    VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings};
-    VkDescriptorSetLayout dsl;
-    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
-    ASSERT_VK_SUCCESS(err);
-
-    VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
-    VkPipelineLayout pl;
-    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
-    ASSERT_VK_SUCCESS(err);
-
-    char const *csSource = "#version 450\n"
-                           "\n"
-                           "layout(local_size_x=1) in;\n"
-                           "layout(set=0, binding=0) uniform texture2D t;\n"
-                           "layout(set=0, binding=1) uniform sampler s;\n"
-                           "layout(set=0, binding=2) buffer block { vec4 x; };\n"
-                           "void main() {\n"
-                           "   x = texture(sampler2D(t, s), vec2(0));\n"
-                           "}\n";
-    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
-
-    VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
-                                        nullptr,
-                                        0,
-                                        {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
-                                         VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
-                                        pl,
-                                        VK_NULL_HANDLE,
-                                        -1};
-
-    VkPipeline pipe;
-    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
-
-    m_errorMonitor->VerifyNotFound();
-
-    if (err == VK_SUCCESS) {
-        vkDestroyPipeline(m_device->device(), pipe, nullptr);
-    }
-
-    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
-    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
-}
-
-TEST_F(VkLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
-    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
-                     "both the sampler and the image of a combined image+sampler "
-                     "but via separate variables");
-    m_errorMonitor->ExpectSuccess();
-
-    ASSERT_NO_FATAL_FAILURE(InitState());
-
-    VkDescriptorSetLayoutBinding bindings[] = {
-        {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-        {1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr},
-    };
-    VkDescriptorSetLayoutCreateInfo dslci = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings};
-    VkDescriptorSetLayout dsl;
-    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
-    ASSERT_VK_SUCCESS(err);
-
-    VkPipelineLayoutCreateInfo plci = {VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr};
-    VkPipelineLayout pl;
-    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
-    ASSERT_VK_SUCCESS(err);
-
-    char const *csSource = "#version 450\n"
-                           "\n"
-                           "layout(local_size_x=1) in;\n"
-                           "layout(set=0, binding=0) uniform texture2D t;\n"
-                           "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
-                           "layout(set=0, binding=1) buffer block { vec4 x; };\n"
-                           "void main() {\n"
-                           "   x = texture(sampler2D(t, s), vec2(0));\n"
-                           "}\n";
-    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
-
-    VkComputePipelineCreateInfo cpci = {VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
-                                        nullptr,
-                                        0,
-                                        {VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
-                                         VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr},
-                                        pl,
-                                        VK_NULL_HANDLE,
-                                        -1};
-
-    VkPipeline pipe;
-    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
-
-    m_errorMonitor->VerifyNotFound();
-
-    if (err == VK_SUCCESS) {
-        vkDestroyPipeline(m_device->device(), pipe, nullptr);
-    }
-
-    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
-    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
-}
-
 TEST_F(VkLayerTest, DrawTimeImageViewTypeMismatchWithPipeline) {
     TEST_DESCRIPTION("Test that an error is produced when an image view type "
                      "does not match the dimensionality declared in the shader");
@@ -15600,8 +13480,8 @@
 
 TEST_F(VkLayerTest, CreateImageViewNoMemoryBoundToImage) {
     VkResult err;
-
-    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "used without first calling vkBindImageMemory");
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+                                         " used with no memory bound. Memory should be bound by calling vkBindImageMemory().");
 
     ASSERT_NO_FATAL_FAILURE(InitState());
 
@@ -15714,6 +13594,7 @@
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &srcImage);
     ASSERT_VK_SUCCESS(err);
 
+    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
     ASSERT_VK_SUCCESS(err);
 
@@ -16115,6 +13996,82 @@
     image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
 }
 
+TEST_F(VkLayerTest, CopyImageSrcSizeExceeded) {
+
+    // Image copy with source region specified greater than src image size
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01175);
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImageObj src_image(m_device);
+    src_image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0);
+    VkImageObj dst_image(m_device);
+    dst_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0);
+
+    BeginCommandBuffer();
+    VkImageCopy copy_region;
+    copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    copy_region.srcSubresource.mipLevel = 0;
+    copy_region.srcSubresource.baseArrayLayer = 0;
+    copy_region.srcSubresource.layerCount = 0;
+    copy_region.srcOffset.x = 0;
+    copy_region.srcOffset.y = 0;
+    copy_region.srcOffset.z = 0;
+    copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    copy_region.dstSubresource.mipLevel = 0;
+    copy_region.dstSubresource.baseArrayLayer = 0;
+    copy_region.dstSubresource.layerCount = 0;
+    copy_region.dstOffset.x = 0;
+    copy_region.dstOffset.y = 0;
+    copy_region.dstOffset.z = 0;
+    copy_region.extent.width = 64;
+    copy_region.extent.height = 64;
+    copy_region.extent.depth = 1;
+    m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
+                               &copy_region);
+    EndCommandBuffer();
+
+    m_errorMonitor->VerifyFound();
+}
+
+TEST_F(VkLayerTest, CopyImageDstSizeExceeded) {
+
+    // Image copy with dest region specified greater than dest image size
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_01176);
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkImageObj src_image(m_device);
+    src_image.init(64, 64, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_IMAGE_TILING_LINEAR, 0);
+    VkImageObj dst_image(m_device);
+    dst_image.init(32, 32, VK_FORMAT_B8G8R8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_TILING_LINEAR, 0);
+
+    BeginCommandBuffer();
+    VkImageCopy copy_region;
+    copy_region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    copy_region.srcSubresource.mipLevel = 0;
+    copy_region.srcSubresource.baseArrayLayer = 0;
+    copy_region.srcSubresource.layerCount = 0;
+    copy_region.srcOffset.x = 0;
+    copy_region.srcOffset.y = 0;
+    copy_region.srcOffset.z = 0;
+    copy_region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+    copy_region.dstSubresource.mipLevel = 0;
+    copy_region.dstSubresource.baseArrayLayer = 0;
+    copy_region.dstSubresource.layerCount = 0;
+    copy_region.dstOffset.x = 0;
+    copy_region.dstOffset.y = 0;
+    copy_region.dstOffset.z = 0;
+    copy_region.extent.width = 64;
+    copy_region.extent.height = 64;
+    copy_region.extent.depth = 1;
+    m_commandBuffer->CopyImage(src_image.image(), VK_IMAGE_LAYOUT_GENERAL, dst_image.image(), VK_IMAGE_LAYOUT_GENERAL, 1,
+                               &copy_region);
+    EndCommandBuffer();
+
+    m_errorMonitor->VerifyFound();
+}
+
 TEST_F(VkLayerTest, CopyImageFormatSizeMismatch) {
     VkResult err;
     bool pass;
@@ -16253,7 +14210,7 @@
     // Introduce failure by creating second image with a depth/stencil format
     image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
     image_create_info.format = VK_FORMAT_D24_UNORM_S8_UINT;
-    image_create_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT;
 
     err = vkCreateImage(m_device->device(), &image_create_info, NULL, &dstImage);
     ASSERT_VK_SUCCESS(err);
@@ -16387,14 +14344,14 @@
     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.srcSubresource.mipLevel = 0;
     resolveRegion.srcSubresource.baseArrayLayer = 0;
-    resolveRegion.srcSubresource.layerCount = 0;
+    resolveRegion.srcSubresource.layerCount = 1;
     resolveRegion.srcOffset.x = 0;
     resolveRegion.srcOffset.y = 0;
     resolveRegion.srcOffset.z = 0;
     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.dstSubresource.mipLevel = 0;
     resolveRegion.dstSubresource.baseArrayLayer = 0;
-    resolveRegion.dstSubresource.layerCount = 0;
+    resolveRegion.dstSubresource.layerCount = 1;
     resolveRegion.dstOffset.x = 0;
     resolveRegion.dstOffset.y = 0;
     resolveRegion.dstOffset.z = 0;
@@ -16489,14 +14446,14 @@
     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.srcSubresource.mipLevel = 0;
     resolveRegion.srcSubresource.baseArrayLayer = 0;
-    resolveRegion.srcSubresource.layerCount = 0;
+    resolveRegion.srcSubresource.layerCount = 1;
     resolveRegion.srcOffset.x = 0;
     resolveRegion.srcOffset.y = 0;
     resolveRegion.srcOffset.z = 0;
     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.dstSubresource.mipLevel = 0;
     resolveRegion.dstSubresource.baseArrayLayer = 0;
-    resolveRegion.dstSubresource.layerCount = 0;
+    resolveRegion.dstSubresource.layerCount = 1;
     resolveRegion.dstOffset.x = 0;
     resolveRegion.dstOffset.y = 0;
     resolveRegion.dstOffset.z = 0;
@@ -16594,14 +14551,14 @@
     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.srcSubresource.mipLevel = 0;
     resolveRegion.srcSubresource.baseArrayLayer = 0;
-    resolveRegion.srcSubresource.layerCount = 0;
+    resolveRegion.srcSubresource.layerCount = 1;
     resolveRegion.srcOffset.x = 0;
     resolveRegion.srcOffset.y = 0;
     resolveRegion.srcOffset.z = 0;
     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.dstSubresource.mipLevel = 0;
     resolveRegion.dstSubresource.baseArrayLayer = 0;
-    resolveRegion.dstSubresource.layerCount = 0;
+    resolveRegion.dstSubresource.layerCount = 1;
     resolveRegion.dstOffset.x = 0;
     resolveRegion.dstOffset.y = 0;
     resolveRegion.dstOffset.z = 0;
@@ -16698,14 +14655,14 @@
     resolveRegion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.srcSubresource.mipLevel = 0;
     resolveRegion.srcSubresource.baseArrayLayer = 0;
-    resolveRegion.srcSubresource.layerCount = 0;
+    resolveRegion.srcSubresource.layerCount = 1;
     resolveRegion.srcOffset.x = 0;
     resolveRegion.srcOffset.y = 0;
     resolveRegion.srcOffset.z = 0;
     resolveRegion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     resolveRegion.dstSubresource.mipLevel = 0;
     resolveRegion.dstSubresource.baseArrayLayer = 0;
-    resolveRegion.dstSubresource.layerCount = 0;
+    resolveRegion.dstSubresource.layerCount = 1;
     resolveRegion.dstOffset.x = 0;
     resolveRegion.dstOffset.y = 0;
     resolveRegion.dstOffset.z = 0;
@@ -16908,6 +14865,4220 @@
 }
 #endif // IMAGE_TESTS
 
+
+// WSI Enabled Tests
+//
+TEST_F(VkWsiEnabledLayerTest, TestEnabledWsi) {
+
+#if defined(VK_USE_PLATFORM_XCB_KHR)
+    VkSurfaceKHR surface = VK_NULL_HANDLE;
+
+    VkResult err;
+    bool pass;
+    VkSwapchainKHR swapchain = VK_NULL_HANDLE;
+    VkSwapchainCreateInfoKHR swapchain_create_info = {};
+    //    uint32_t swapchain_image_count = 0;
+    //    VkImage swapchain_images[1] = {VK_NULL_HANDLE};
+    //    uint32_t image_index = 0;
+    //    VkPresentInfoKHR present_info = {};
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Use the create function from one of the VK_KHR_*_surface extension in
+    // order to create a surface, testing all known errors in the process,
+    // before successfully creating a surface:
+    // First, try to create a surface without a VkXcbSurfaceCreateInfoKHR:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo specified as NULL");
+    err = vkCreateXcbSurfaceKHR(instance(), NULL, NULL, &surface);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, try to create a surface with the wrong
+    // VkXcbSurfaceCreateInfoKHR::sType:
+    VkXcbSurfaceCreateInfoKHR xcb_create_info = {};
+    xcb_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
+    err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Create a native window, and then correctly create a surface:
+    xcb_connection_t *connection;
+    xcb_screen_t *screen;
+    xcb_window_t xcb_window;
+    xcb_intern_atom_reply_t *atom_wm_delete_window;
+
+    const xcb_setup_t *setup;
+    xcb_screen_iterator_t iter;
+    int scr;
+    uint32_t value_mask, value_list[32];
+    int width = 1;
+    int height = 1;
+
+    connection = xcb_connect(NULL, &scr);
+    ASSERT_TRUE(connection != NULL);
+    setup = xcb_get_setup(connection);
+    iter = xcb_setup_roots_iterator(setup);
+    while (scr-- > 0)
+        xcb_screen_next(&iter);
+    screen = iter.data;
+
+    xcb_window = xcb_generate_id(connection);
+
+    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+    value_list[0] = screen->black_pixel;
+    value_list[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+
+    xcb_create_window(connection, XCB_COPY_FROM_PARENT, xcb_window, screen->root, 0, 0, width, height, 0,
+        XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, value_mask, value_list);
+
+    /* Magic code that will send notification when window is destroyed */
+    xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, 1, 12, "WM_PROTOCOLS");
+    xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, cookie, 0);
+
+    xcb_intern_atom_cookie_t cookie2 = xcb_intern_atom(connection, 0, 16, "WM_DELETE_WINDOW");
+    atom_wm_delete_window = xcb_intern_atom_reply(connection, cookie2, 0);
+    xcb_change_property(connection, XCB_PROP_MODE_REPLACE, xcb_window, (*reply).atom, 4, 32, 1, &(*atom_wm_delete_window).atom);
+    free(reply);
+
+    xcb_map_window(connection, xcb_window);
+
+    // Force the x/y coordinates to 100,100 results are identical in consecutive
+    // runs
+    const uint32_t coords[] = { 100, 100 };
+    xcb_configure_window(connection, xcb_window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
+
+    // Finally, try to correctly create a surface:
+    xcb_create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
+    xcb_create_info.pNext = NULL;
+    xcb_create_info.flags = 0;
+    xcb_create_info.connection = connection;
+    xcb_create_info.window = xcb_window;
+    err = vkCreateXcbSurfaceKHR(instance(), &xcb_create_info, NULL, &surface);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Check if surface supports presentation:
+
+    // 1st, do so without having queried the queue families:
+    VkBool32 supported = false;
+    // TODO: Get the following error to come out:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "called before calling the vkGetPhysicalDeviceQueueFamilyProperties "
+        "function");
+    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
+    pass = (err != VK_SUCCESS);
+    //    ASSERT_TRUE(pass);
+    //    m_errorMonitor->VerifyFound();
+
+    // Next, query a queue family index that's too large:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
+    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 100000, surface, &supported);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Finally, do so correctly:
+    // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
+    // SUPPORTED
+    err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu(), 0, surface, &supported);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Before proceeding, try to create a swapchain without having called
+    // vkGetPhysicalDeviceSurfaceCapabilitiesKHR():
+    swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+    swapchain_create_info.pNext = NULL;
+    swapchain_create_info.flags = 0;
+    swapchain_create_info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+    swapchain_create_info.surface = surface;
+    swapchain_create_info.imageArrayLayers = 1;
+    swapchain_create_info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
+    swapchain_create_info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "called before calling vkGetPhysicalDeviceSurfaceCapabilitiesKHR().");
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Get the surface capabilities:
+    VkSurfaceCapabilitiesKHR surface_capabilities;
+
+    // Do so correctly (only error logged by this entrypoint is if the
+    // extension isn't enabled):
+    err = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu(), surface, &surface_capabilities);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Get the surface formats:
+    uint32_t surface_format_count;
+
+    // First, try without a pointer to surface_format_count:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSurfaceFormatCount "
+        "specified as NULL");
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, NULL, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call with a non-NULL pSurfaceFormats, even though we haven't
+    // correctly done a 1st try (to get the count):
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
+    surface_format_count = 0;
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, (VkSurfaceFormatKHR *)&surface_format_count);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Allocate memory for the correct number of VkSurfaceFormatKHR's:
+    VkSurfaceFormatKHR *surface_formats = (VkSurfaceFormatKHR *)malloc(surface_format_count * sizeof(VkSurfaceFormatKHR));
+
+    // Next, do a 2nd try with surface_format_count being set too high:
+    surface_format_count += 5;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Finally, do a correct 1st and 2nd try:
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    vkGetPhysicalDeviceSurfaceFormatsKHR(gpu(), surface, &surface_format_count, surface_formats);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Get the surface present modes:
+    uint32_t surface_present_mode_count;
+
+    // First, try without a pointer to surface_format_count:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pPresentModeCount "
+        "specified as NULL");
+
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, NULL, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call with a non-NULL VkPresentModeKHR, even though we haven't
+    // correctly done a 1st try (to get the count):
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_WARNING_BIT_EXT, "but no prior positive value has been seen for");
+    surface_present_mode_count = 0;
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count,
+        (VkPresentModeKHR *)&surface_present_mode_count);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, correctly do a 1st try (with a NULL pointer to surface_formats):
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Allocate memory for the correct number of VkSurfaceFormatKHR's:
+    VkPresentModeKHR *surface_present_modes = (VkPresentModeKHR *)malloc(surface_present_mode_count * sizeof(VkPresentModeKHR));
+
+    // Next, do a 2nd try with surface_format_count being set too high:
+    surface_present_mode_count += 5;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is greater than the value");
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Finally, do a correct 1st and 2nd try:
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, NULL);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    vkGetPhysicalDeviceSurfacePresentModesKHR(gpu(), surface, &surface_present_mode_count, surface_present_modes);
+    pass = (err == VK_SUCCESS);
+    ASSERT_TRUE(pass);
+
+    // Create a swapchain:
+
+    // First, try without a pointer to swapchain_create_info:
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pCreateInfo "
+        "specified as NULL");
+
+    err = vkCreateSwapchainKHR(m_device->device(), NULL, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call with a non-NULL swapchain_create_info, that has the wrong
+    // sType:
+    swapchain_create_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "parameter pCreateInfo->sType must be");
+
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call with a NULL swapchain pointer:
+    swapchain_create_info.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
+    swapchain_create_info.pNext = NULL;
+    swapchain_create_info.flags = 0;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "required parameter pSwapchain "
+        "specified as NULL");
+
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, NULL);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // TODO: Enhance swapchain layer so that
+    // swapchain_create_info.queueFamilyIndexCount is checked against something?
+
+    // Next, call with a queue family index that's too large:
+    uint32_t queueFamilyIndex[2] = { 100000, 0 };
+    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+    swapchain_create_info.queueFamilyIndexCount = 2;
+    swapchain_create_info.pQueueFamilyIndices = queueFamilyIndex;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "called with a queueFamilyIndex that is too large");
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call a queueFamilyIndexCount that's too small for CONCURRENT:
+    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
+    swapchain_create_info.queueFamilyIndexCount = 1;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "but with a bad value(s) for pCreateInfo->queueFamilyIndexCount or "
+        "pCreateInfo->pQueueFamilyIndices).");
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+
+    // Next, call with an invalid imageSharingMode:
+    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_MAX_ENUM;
+    swapchain_create_info.queueFamilyIndexCount = 1;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT,
+        "called with a non-supported pCreateInfo->imageSharingMode (i.e.");
+    err = vkCreateSwapchainKHR(m_device->device(), &swapchain_create_info, NULL, &swapchain);
+    pass = (err != VK_SUCCESS);
+    ASSERT_TRUE(pass);
+    m_errorMonitor->VerifyFound();
+    // Fix for the future:
+    // FIXME: THIS ISN'T CORRECT--MUST QUERY UNTIL WE FIND A QUEUE FAMILY THAT'S
+    // SUPPORTED
+    swapchain_create_info.queueFamilyIndexCount = 0;
+    queueFamilyIndex[0] = 0;
+    swapchain_create_info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+    // TODO: CONTINUE TESTING VALIDATION OF vkCreateSwapchainKHR() ...
+    // Get the images from a swapchain:
+    // Acquire an image from a swapchain:
+    // Present an image to a swapchain:
+    // Destroy the swapchain:
+
+    // TODOs:
+    //
+    // - Try destroying the device without first destroying the swapchain
+    //
+    // - Try destroying the device without first destroying the surface
+    //
+    // - Try destroying the surface without first destroying the swapchain
+
+    // Destroy the surface:
+    vkDestroySurfaceKHR(instance(), surface, NULL);
+
+    // Tear down the window:
+    xcb_destroy_window(connection, xcb_window);
+    xcb_disconnect(connection);
+
+#else  // VK_USE_PLATFORM_XCB_KHR
+    return;
+#endif // VK_USE_PLATFORM_XCB_KHR
+}
+
+//
+// POSITIVE VALIDATION TESTS
+//
+// These tests do not expect to encounter ANY validation errors pass only if this is true
+
+// This is a positive test. No failures are expected.
+TEST_F(VkPositiveLayerTest, IgnoreUnrelatedDescriptor) {
+    TEST_DESCRIPTION("Ensure that the vkUpdateDescriptorSets validation code "
+        "is ignoring VkWriteDescriptorSet members that are not "
+        "related to the descriptor type specified by "
+        "VkWriteDescriptorSet::descriptorType.  Correct "
+        "validation behavior will result in the test running to "
+        "completion without validation errors.");
+
+    const uintptr_t invalid_ptr = 0xcdcdcdcd;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Image Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkImage image;
+        const VkFormat tex_format = VK_FORMAT_B8G8R8A8_UNORM;
+        const int32_t tex_width = 32;
+        const int32_t tex_height = 32;
+        VkImageCreateInfo image_create_info = {};
+        image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+        image_create_info.pNext = NULL;
+        image_create_info.imageType = VK_IMAGE_TYPE_2D;
+        image_create_info.format = tex_format;
+        image_create_info.extent.width = tex_width;
+        image_create_info.extent.height = tex_height;
+        image_create_info.extent.depth = 1;
+        image_create_info.mipLevels = 1;
+        image_create_info.arrayLayers = 1;
+        image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+        image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+        image_create_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+        image_create_info.flags = 0;
+        VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory image_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+        vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+        ASSERT_TRUE(pass);
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &image_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindImageMemory(m_device->device(), image, image_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkImageViewCreateInfo image_view_create_info = {};
+        image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+        image_view_create_info.image = image;
+        image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;
+        image_view_create_info.format = tex_format;
+        image_view_create_info.subresourceRange.layerCount = 1;
+        image_view_create_info.subresourceRange.baseMipLevel = 0;
+        image_view_create_info.subresourceRange.levelCount = 1;
+        image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+        VkImageView view;
+        err = vkCreateImageView(m_device->device(), &image_view_create_info, NULL, &view);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorImageInfo image_info = {};
+        image_info.imageView = view;
+        image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
+        descriptor_write.pImageInfo = &image_info;
+
+        // Set pBufferInfo and pTexelBufferView to invalid values, which should
+        // be
+        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pBufferInfo.
+        descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
+        descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyImageView(m_device->device(), view, NULL);
+        vkDestroyImage(m_device->device(), image, NULL);
+        vkFreeMemory(m_device->device(), image_memory, NULL);
+    }
+
+    // Buffer Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkBuffer buffer;
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory buffer_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorBufferInfo buffer_info = {};
+        buffer_info.buffer = buffer;
+        buffer_info.offset = 0;
+        buffer_info.range = 1024;
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+        descriptor_write.pBufferInfo = &buffer_info;
+
+        // Set pImageInfo and pTexelBufferView to invalid values, which should
+        // be
+        //  ignored for descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pImageInfo.
+        descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
+        descriptor_write.pTexelBufferView = reinterpret_cast<const VkBufferView *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    }
+
+    // Texel Buffer Case
+    {
+        m_errorMonitor->ExpectSuccess();
+
+        VkBuffer buffer;
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        VkDeviceMemory buffer_memory;
+        bool pass;
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = NULL;
+        memory_info.allocationSize = 0;
+        memory_info.memoryTypeIndex = 0;
+
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+        memory_info.allocationSize = memory_reqs.size;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        VkBufferViewCreateInfo buff_view_ci = {};
+        buff_view_ci.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
+        buff_view_ci.buffer = buffer;
+        buff_view_ci.format = VK_FORMAT_R8_UNORM;
+        buff_view_ci.range = VK_WHOLE_SIZE;
+        VkBufferView buffer_view;
+        err = vkCreateBufferView(m_device->device(), &buff_view_ci, NULL, &buffer_view);
+
+        VkDescriptorPoolSize ds_type_count = {};
+        ds_type_count.type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        ds_type_count.descriptorCount = 1;
+
+        VkDescriptorPoolCreateInfo ds_pool_ci = {};
+        ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+        ds_pool_ci.pNext = NULL;
+        ds_pool_ci.maxSets = 1;
+        ds_pool_ci.poolSizeCount = 1;
+        ds_pool_ci.pPoolSizes = &ds_type_count;
+
+        VkDescriptorPool ds_pool;
+        err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSetLayoutBinding dsl_binding = {};
+        dsl_binding.binding = 0;
+        dsl_binding.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        dsl_binding.descriptorCount = 1;
+        dsl_binding.stageFlags = VK_SHADER_STAGE_ALL;
+        dsl_binding.pImmutableSamplers = NULL;
+
+        VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+        ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+        ds_layout_ci.pNext = NULL;
+        ds_layout_ci.bindingCount = 1;
+        ds_layout_ci.pBindings = &dsl_binding;
+        VkDescriptorSetLayout ds_layout;
+        err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+        ASSERT_VK_SUCCESS(err);
+
+        VkDescriptorSet descriptor_set;
+        VkDescriptorSetAllocateInfo alloc_info = {};
+        alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+        alloc_info.descriptorSetCount = 1;
+        alloc_info.descriptorPool = ds_pool;
+        alloc_info.pSetLayouts = &ds_layout;
+        err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+        ASSERT_VK_SUCCESS(err);
+
+        VkWriteDescriptorSet descriptor_write;
+        memset(&descriptor_write, 0, sizeof(descriptor_write));
+        descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+        descriptor_write.dstSet = descriptor_set;
+        descriptor_write.dstBinding = 0;
+        descriptor_write.descriptorCount = 1;
+        descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
+        descriptor_write.pTexelBufferView = &buffer_view;
+
+        // Set pImageInfo and pBufferInfo to invalid values, which should be
+        //  ignored for descriptorType ==
+        //  VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER.
+        // This will most likely produce a crash if the parameter_validation
+        // layer
+        // does not correctly ignore pImageInfo and pBufferInfo.
+        descriptor_write.pImageInfo = reinterpret_cast<const VkDescriptorImageInfo *>(invalid_ptr);
+        descriptor_write.pBufferInfo = reinterpret_cast<const VkDescriptorBufferInfo *>(invalid_ptr);
+
+        vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+        m_errorMonitor->VerifyNotFound();
+
+        vkFreeDescriptorSets(m_device->device(), ds_pool, 1, &descriptor_set);
+        vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+        vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+        vkDestroyBufferView(m_device->device(), buffer_view, NULL);
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+    }
+}
+
+TEST_F(VkLayerTest, DuplicateDescriptorBinding) {
+    TEST_DESCRIPTION("Create a descriptor set layout with a duplicate binding number.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    // Create layout where two binding #s are "1"
+    static const uint32_t NUM_BINDINGS = 3;
+    VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {};
+    dsl_binding[0].binding = 1;
+    dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding[0].descriptorCount = 1;
+    dsl_binding[0].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    dsl_binding[0].pImmutableSamplers = NULL;
+    dsl_binding[1].binding = 0;
+    dsl_binding[1].descriptorCount = 1;
+    dsl_binding[1].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding[1].descriptorCount = 1;
+    dsl_binding[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    dsl_binding[1].pImmutableSamplers = NULL;
+    dsl_binding[2].binding = 1; // Duplicate binding should cause error
+    dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding[2].descriptorCount = 1;
+    dsl_binding[2].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
+    dsl_binding[2].pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = NUM_BINDINGS;
+    ds_layout_ci.pBindings = dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, VALIDATION_ERROR_02345);
+    vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    m_errorMonitor->VerifyFound();
+}
+
+// This is a positive test. No failures are expected.
+TEST_F(VkPositiveLayerTest, EmptyDescriptorUpdateTest) {
+    TEST_DESCRIPTION("Update last descriptor in a set that includes an empty binding");
+    VkResult err;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    m_errorMonitor->ExpectSuccess();
+    VkDescriptorPoolSize ds_type_count = {};
+    ds_type_count.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    ds_type_count.descriptorCount = 2;
+
+    VkDescriptorPoolCreateInfo ds_pool_ci = {};
+    ds_pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+    ds_pool_ci.pNext = NULL;
+    ds_pool_ci.maxSets = 1;
+    ds_pool_ci.poolSizeCount = 1;
+    ds_pool_ci.pPoolSizes = &ds_type_count;
+
+    VkDescriptorPool ds_pool;
+    err = vkCreateDescriptorPool(m_device->device(), &ds_pool_ci, NULL, &ds_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create layout with two uniform buffer descriptors w/ empty binding between them
+    static const uint32_t NUM_BINDINGS = 3;
+    VkDescriptorSetLayoutBinding dsl_binding[NUM_BINDINGS] = {};
+    dsl_binding[0].binding = 0;
+    dsl_binding[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding[0].descriptorCount = 1;
+    dsl_binding[0].stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding[0].pImmutableSamplers = NULL;
+    dsl_binding[1].binding = 1;
+    dsl_binding[1].descriptorCount = 0; // empty binding
+    dsl_binding[2].binding = 2;
+    dsl_binding[2].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    dsl_binding[2].descriptorCount = 1;
+    dsl_binding[2].stageFlags = VK_SHADER_STAGE_ALL;
+    dsl_binding[2].pImmutableSamplers = NULL;
+
+    VkDescriptorSetLayoutCreateInfo ds_layout_ci = {};
+    ds_layout_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+    ds_layout_ci.pNext = NULL;
+    ds_layout_ci.bindingCount = NUM_BINDINGS;
+    ds_layout_ci.pBindings = dsl_binding;
+    VkDescriptorSetLayout ds_layout;
+    err = vkCreateDescriptorSetLayout(m_device->device(), &ds_layout_ci, NULL, &ds_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkDescriptorSet descriptor_set = {};
+    VkDescriptorSetAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+    alloc_info.descriptorSetCount = 1;
+    alloc_info.descriptorPool = ds_pool;
+    alloc_info.pSetLayouts = &ds_layout;
+    err = vkAllocateDescriptorSets(m_device->device(), &alloc_info, &descriptor_set);
+    ASSERT_VK_SUCCESS(err);
+
+    // Create a buffer to be used for update
+    VkBufferCreateInfo buff_ci = {};
+    buff_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_ci.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buff_ci.size = 256;
+    buff_ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_ci, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+    // Have to bind memory to buffer before descriptor update
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 512; // one allocation for both buffers
+    mem_alloc.memoryTypeIndex = 0;
+
+    VkMemoryRequirements mem_reqs;
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+    bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, 0);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    VkDeviceMemory mem;
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    // Only update the descriptor at binding 2
+    VkDescriptorBufferInfo buff_info = {};
+    buff_info.buffer = buffer;
+    buff_info.offset = 0;
+    buff_info.range = VK_WHOLE_SIZE;
+    VkWriteDescriptorSet descriptor_write = {};
+    descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+    descriptor_write.dstBinding = 2;
+    descriptor_write.descriptorCount = 1;
+    descriptor_write.pTexelBufferView = nullptr;
+    descriptor_write.pBufferInfo = &buff_info;
+    descriptor_write.pImageInfo = nullptr;
+    descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
+    descriptor_write.dstSet = descriptor_set;
+
+    vkUpdateDescriptorSets(m_device->device(), 1, &descriptor_write, 0, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+    // Cleanup
+    vkFreeMemory(m_device->device(), mem, NULL);
+    vkDestroyDescriptorSetLayout(m_device->device(), ds_layout, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkDestroyDescriptorPool(m_device->device(), ds_pool, NULL);
+}
+
+// This is a positive test. No failures are expected.
+TEST_F(VkPositiveLayerTest, TestAliasedMemoryTracking) {
+    VkResult err;
+    bool pass;
+
+    TEST_DESCRIPTION("Create a buffer, allocate memory, bind memory, destroy "
+        "the buffer, create an image, and bind the same memory to "
+        "it");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkBuffer buffer;
+    VkImage image;
+    VkDeviceMemory mem;
+    VkMemoryRequirements mem_reqs;
+
+    VkBufferCreateInfo buf_info = {};
+    buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buf_info.pNext = NULL;
+    buf_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+    buf_info.size = 256;
+    buf_info.queueFamilyIndexCount = 0;
+    buf_info.pQueueFamilyIndices = NULL;
+    buf_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    buf_info.flags = 0;
+    err = vkCreateBuffer(m_device->device(), &buf_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &mem_reqs);
+
+    VkMemoryAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    alloc_info.pNext = NULL;
+    alloc_info.memoryTypeIndex = 0;
+
+    // Ensure memory is big enough for both bindings
+    alloc_info.allocationSize = 0x10000;
+
+    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+
+    uint8_t *pData;
+    err = vkMapMemory(m_device->device(), mem, 0, mem_reqs.size, 0, (void **)&pData);
+    ASSERT_VK_SUCCESS(err);
+
+    memset(pData, 0xCADECADE, static_cast<size_t>(mem_reqs.size));
+
+    vkUnmapMemory(m_device->device(), mem);
+
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    // NOW, destroy the buffer. Obviously, the resource no longer occupies this
+    // memory. In fact, it was never used by the GPU.
+    // Just be be sure, wait for idle.
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkDeviceWaitIdle(m_device->device());
+
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = VK_FORMAT_R8G8B8A8_UNORM;
+    image_create_info.extent.width = 64;
+    image_create_info.extent.height = 64;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_LINEAR;
+    image_create_info.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED;
+    image_create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+    image_create_info.queueFamilyIndexCount = 0;
+    image_create_info.pQueueFamilyIndices = NULL;
+    image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    image_create_info.flags = 0;
+
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 0;
+    mem_alloc.memoryTypeIndex = 0;
+
+    /* Create a mappable image.  It will be the texture if linear images are ok
+    * to be textures or it will be the staging image if they are not.
+    */
+    err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+
+    vkGetImageMemoryRequirements(m_device->device(), image, &mem_reqs);
+
+    mem_alloc.allocationSize = mem_reqs.size;
+
+    pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &mem_alloc, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
+    if (!pass) {
+        vkDestroyImage(m_device->device(), image, NULL);
+        return;
+    }
+
+    // VALIDATION FAILURE:
+    err = vkBindImageMemory(m_device->device(), image, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    m_errorMonitor->VerifyNotFound();
+
+    vkFreeMemory(m_device->device(), mem, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkDestroyImage(m_device->device(), image, NULL);
+}
+
+TEST_F(VkPositiveLayerTest, NonCoherentMemoryMapping) {
+
+    TEST_DESCRIPTION("Ensure that validations handling of non-coherent memory "
+        "mapping while using VK_WHOLE_SIZE does not cause access "
+        "violations");
+    VkResult err;
+    uint8_t *pData;
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDeviceMemory mem;
+    VkMemoryRequirements mem_reqs;
+    mem_reqs.memoryTypeBits = 0xFFFFFFFF;
+    VkMemoryAllocateInfo alloc_info = {};
+    alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    alloc_info.pNext = NULL;
+    alloc_info.memoryTypeIndex = 0;
+
+    static const VkDeviceSize allocation_size = 0x1000;
+    alloc_info.allocationSize = allocation_size;
+
+    // Find a memory configurations WITHOUT a COHERENT bit, otherwise exit
+    bool pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+        VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+    if (!pass) {
+        pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
+            VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+            VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+        if (!pass) {
+            pass = m_device->phy().set_memory_type(mem_reqs.memoryTypeBits, &alloc_info,
+                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
+                VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+                VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+            if (!pass) {
+                return;
+            }
+        }
+    }
+
+    err = vkAllocateMemory(m_device->device(), &alloc_info, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+
+    // Map/Flush/Invalidate using WHOLE_SIZE and zero offsets and entire
+    // mapped range
+    m_errorMonitor->ExpectSuccess();
+    err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
+    ASSERT_VK_SUCCESS(err);
+    VkMappedMemoryRange mmr = {};
+    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+    mmr.memory = mem;
+    mmr.offset = 0;
+    mmr.size = VK_WHOLE_SIZE;
+    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    m_errorMonitor->VerifyNotFound();
+    vkUnmapMemory(m_device->device(), mem);
+
+    // Map/Flush/Invalidate using WHOLE_SIZE and a prime offset and entire
+    // mapped range
+    m_errorMonitor->ExpectSuccess();
+    err = vkMapMemory(m_device->device(), mem, 13, VK_WHOLE_SIZE, 0, (void **)&pData);
+    ASSERT_VK_SUCCESS(err);
+    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+    mmr.memory = mem;
+    mmr.offset = 13;
+    mmr.size = VK_WHOLE_SIZE;
+    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    m_errorMonitor->VerifyNotFound();
+    vkUnmapMemory(m_device->device(), mem);
+
+    // Map with prime offset and size
+    // Flush/Invalidate subrange of mapped area with prime offset and size
+    m_errorMonitor->ExpectSuccess();
+    err = vkMapMemory(m_device->device(), mem, allocation_size - 137, 109, 0, (void **)&pData);
+    ASSERT_VK_SUCCESS(err);
+    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+    mmr.memory = mem;
+    mmr.offset = allocation_size - 107;
+    mmr.size = 61;
+    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    err = vkInvalidateMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    m_errorMonitor->VerifyNotFound();
+    vkUnmapMemory(m_device->device(), mem);
+
+    // Map without offset and flush WHOLE_SIZE with two separate offsets
+    m_errorMonitor->ExpectSuccess();
+    err = vkMapMemory(m_device->device(), mem, 0, VK_WHOLE_SIZE, 0, (void **)&pData);
+    ASSERT_VK_SUCCESS(err);
+    mmr.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
+    mmr.memory = mem;
+    mmr.offset = allocation_size - 100;
+    mmr.size = VK_WHOLE_SIZE;
+    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    mmr.offset = allocation_size - 200;
+    mmr.size = VK_WHOLE_SIZE;
+    err = vkFlushMappedMemoryRanges(m_device->device(), 1, &mmr);
+    ASSERT_VK_SUCCESS(err);
+    m_errorMonitor->VerifyNotFound();
+    vkUnmapMemory(m_device->device(), mem);
+
+    vkFreeMemory(m_device->device(), mem, NULL);
+}
+
+// This is a positive test. We used to expect error in this case but spec now allows it
+TEST_F(VkPositiveLayerTest, ResetUnsignaledFence) {
+    m_errorMonitor->ExpectSuccess();
+    vk_testing::Fence testFence;
+    VkFenceCreateInfo fenceInfo = {};
+    fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fenceInfo.pNext = NULL;
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    testFence.init(*m_device, fenceInfo);
+    VkFence fences[1] = { testFence.handle() };
+    VkResult result = vkResetFences(m_device->device(), 1, fences);
+    ASSERT_VK_SUCCESS(result);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CommandBufferSimultaneousUseSync) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    // Record (empty!) command buffer that can be submitted multiple times
+    // simultaneously.
+    VkCommandBufferBeginInfo cbbi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr,
+        VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, nullptr };
+    m_commandBuffer->BeginCommandBuffer(&cbbi);
+    m_commandBuffer->EndCommandBuffer();
+
+    VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+    VkFence fence;
+    err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
+    ASSERT_VK_SUCCESS(err);
+
+    VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
+    VkSemaphore s1, s2;
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s1);
+    ASSERT_VK_SUCCESS(err);
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s2);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit CB once signaling s1, with fence so we can roll forward to its retirement.
+    VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &m_commandBuffer->handle(), 1, &s1 };
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit CB again, signaling s2.
+    si.pSignalSemaphores = &s2;
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Wait for fence.
+    err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    ASSERT_VK_SUCCESS(err);
+
+    // CB is still in flight from second submission, but semaphore s1 is no
+    // longer in flight. delete it.
+    vkDestroySemaphore(m_device->device(), s1, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+
+    // Force device idle and clean up remaining objects
+    vkDeviceWaitIdle(m_device->device());
+    vkDestroySemaphore(m_device->device(), s2, nullptr);
+    vkDestroyFence(m_device->device(), fence, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, FenceCreateSignaledWaitHandling) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    // A fence created signaled
+    VkFenceCreateInfo fci1 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, VK_FENCE_CREATE_SIGNALED_BIT };
+    VkFence f1;
+    err = vkCreateFence(m_device->device(), &fci1, nullptr, &f1);
+    ASSERT_VK_SUCCESS(err);
+
+    // A fence created not
+    VkFenceCreateInfo fci2 = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+    VkFence f2;
+    err = vkCreateFence(m_device->device(), &fci2, nullptr, &f2);
+    ASSERT_VK_SUCCESS(err);
+
+    // Submit the unsignaled fence
+    VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 0, nullptr, 0, nullptr };
+    err = vkQueueSubmit(m_device->m_queue, 1, &si, f2);
+
+    // Wait on both fences, with signaled first.
+    VkFence fences[] = { f1, f2 };
+    vkWaitForFences(m_device->device(), 2, fences, VK_TRUE, UINT64_MAX);
+
+    // Should have both retired!
+    vkDestroyFence(m_device->device(), f1, nullptr);
+    vkDestroyFence(m_device->device(), f2, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, ValidUsage) {
+    TEST_DESCRIPTION("Verify that creating an image view from an image with valid usage "
+        "doesn't generate validation errors");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    m_errorMonitor->ExpectSuccess();
+    // Verify that we can create a view with usage INPUT_ATTACHMENT
+    VkImageObj image(m_device);
+    image.init(128, 128, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+    VkImageView imageView;
+    VkImageViewCreateInfo ivci = {};
+    ivci.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+    ivci.image = image.handle();
+    ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    ivci.format = VK_FORMAT_R8G8B8A8_UNORM;
+    ivci.subresourceRange.layerCount = 1;
+    ivci.subresourceRange.baseMipLevel = 0;
+    ivci.subresourceRange.levelCount = 1;
+    ivci.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+    vkCreateImageView(m_device->device(), &ivci, NULL, &imageView);
+    m_errorMonitor->VerifyNotFound();
+    vkDestroyImageView(m_device->device(), imageView, NULL);
+}
+
+// This is a positive test. No failures are expected.
+TEST_F(VkPositiveLayerTest, BindSparse) {
+    TEST_DESCRIPTION("Bind 2 memory ranges to one image using vkQueueBindSparse, destroy the image"
+        "and then free the memory");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    auto index = m_device->graphics_queue_node_index_;
+    if (!(m_device->queue_props[index].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkImage image;
+    VkImageCreateInfo image_create_info = {};
+    image_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    image_create_info.pNext = NULL;
+    image_create_info.imageType = VK_IMAGE_TYPE_2D;
+    image_create_info.format = VK_FORMAT_B8G8R8A8_UNORM;
+    image_create_info.extent.width = 64;
+    image_create_info.extent.height = 64;
+    image_create_info.extent.depth = 1;
+    image_create_info.mipLevels = 1;
+    image_create_info.arrayLayers = 1;
+    image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
+    image_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    image_create_info.usage = VK_IMAGE_USAGE_STORAGE_BIT;
+    image_create_info.flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
+    VkResult err = vkCreateImage(m_device->device(), &image_create_info, NULL, &image);
+    ASSERT_VK_SUCCESS(err);
+
+    VkMemoryRequirements memory_reqs;
+    VkDeviceMemory memory_one, memory_two;
+    bool pass;
+    VkMemoryAllocateInfo memory_info = {};
+    memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    memory_info.pNext = NULL;
+    memory_info.allocationSize = 0;
+    memory_info.memoryTypeIndex = 0;
+    vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+    // Find an image big enough to allow sparse mapping of 2 memory regions
+    // Increase the image size until it is at least twice the
+    // size of the required alignment, to ensure we can bind both
+    // allocated memory blocks to the image on aligned offsets.
+    while (memory_reqs.size < (memory_reqs.alignment * 2)) {
+        vkDestroyImage(m_device->device(), image, nullptr);
+        image_create_info.extent.width *= 2;
+        image_create_info.extent.height *= 2;
+        err = vkCreateImage(m_device->device(), &image_create_info, nullptr, &image);
+        ASSERT_VK_SUCCESS(err);
+        vkGetImageMemoryRequirements(m_device->device(), image, &memory_reqs);
+    }
+    // Allocate 2 memory regions of minimum alignment size, bind one at 0, the other
+    // at the end of the first
+    memory_info.allocationSize = memory_reqs.alignment;
+    pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+    ASSERT_TRUE(pass);
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_one);
+    ASSERT_VK_SUCCESS(err);
+    err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &memory_two);
+    ASSERT_VK_SUCCESS(err);
+    VkSparseMemoryBind binds[2];
+    binds[0].flags = 0;
+    binds[0].memory = memory_one;
+    binds[0].memoryOffset = 0;
+    binds[0].resourceOffset = 0;
+    binds[0].size = memory_info.allocationSize;
+    binds[1].flags = 0;
+    binds[1].memory = memory_two;
+    binds[1].memoryOffset = 0;
+    binds[1].resourceOffset = memory_info.allocationSize;
+    binds[1].size = memory_info.allocationSize;
+
+    VkSparseImageOpaqueMemoryBindInfo opaqueBindInfo;
+    opaqueBindInfo.image = image;
+    opaqueBindInfo.bindCount = 2;
+    opaqueBindInfo.pBinds = binds;
+
+    VkFence fence = VK_NULL_HANDLE;
+    VkBindSparseInfo bindSparseInfo = {};
+    bindSparseInfo.sType = VK_STRUCTURE_TYPE_BIND_SPARSE_INFO;
+    bindSparseInfo.imageOpaqueBindCount = 1;
+    bindSparseInfo.pImageOpaqueBinds = &opaqueBindInfo;
+
+    vkQueueBindSparse(m_device->m_queue, 1, &bindSparseInfo, fence);
+    vkQueueWaitIdle(m_device->m_queue);
+    vkDestroyImage(m_device->device(), image, NULL);
+    vkFreeMemory(m_device->device(), memory_one, NULL);
+    vkFreeMemory(m_device->device(), memory_two, NULL);
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, RenderPassInitialLayoutUndefined) {
+    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass with an attachment's "
+        "initialLayout of VK_IMAGE_LAYOUT_UNDEFINED works when "
+        "the command buffer has prior knowledge of that "
+        "attachment's layout.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = { 0,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr };
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
+        VK_COMPONENT_SWIZZLE_IDENTITY },
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a single command buffer which uses this renderpass twice. The
+    // bug is triggered at the beginning of the second renderpass, when the
+    // command buffer already has a layout recorded for the attachment.
+    VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+
+    m_errorMonitor->VerifyNotFound();
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, FramebufferBindingDestroyCommandPool) {
+    TEST_DESCRIPTION("This test should pass. Create a Framebuffer and "
+        "command buffer, bind them together, then destroy "
+        "command pool and framebuffer and verify there are no "
+        "errors.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = { 0,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr };
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 0, nullptr };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
+        VK_COMPONENT_SWIZZLE_IDENTITY },
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Explicitly create a command buffer to bind the FB to so that we can then
+    //  destroy the command pool in order to implicitly free command buffer
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
+
+    // Begin our cmd buffer with renderpass using our framebuffer
+    VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr };
+    VkCommandBufferBeginInfo begin_info{};
+    begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+    vkBeginCommandBuffer(command_buffer, &begin_info);
+
+    vkCmdBeginRenderPass(command_buffer, &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(command_buffer);
+    vkEndCommandBuffer(command_buffer);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+    // Destroy command pool to implicitly free command buffer
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, RenderPassSubpassZeroTransitionsApplied) {
+    TEST_DESCRIPTION("Ensure that CmdBeginRenderPass applies the layout "
+        "transitions for the first subpass");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with one color attachment.
+    VkAttachmentDescription attachment = { 0,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_UNDEFINED,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr };
+
+    VkSubpassDependency dep = { 0,
+        0,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_DEPENDENCY_BY_REGION_BIT };
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep };
+
+    VkResult err;
+    VkRenderPass rp;
+    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkImageObj image(m_device);
+    image.init(32, 32, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_R8G8B8A8_UNORM,
+        { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
+        VK_COMPONENT_SWIZZLE_IDENTITY },
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a single command buffer which issues a pipeline barrier w/
+    // image memory barrier for the attachment. This detects the previously
+    // missing tracking of the subpass layout by throwing a validation error
+    // if it doesn't occur.
+    VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+
+    VkImageMemoryBarrier imb = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+        nullptr,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        VK_QUEUE_FAMILY_IGNORED,
+        VK_QUEUE_FAMILY_IGNORED,
+        image.handle(),
+        { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } };
+    vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
+        &imb);
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    m_errorMonitor->VerifyNotFound();
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, DepthStencilLayoutTransitionForDepthOnlyImageview) {
+    TEST_DESCRIPTION("Validate that when an imageView of a depth/stencil image "
+        "is used as a depth/stencil framebuffer attachment, the "
+        "aspectMask is ignored and both depth and stencil image "
+        "subresources are used.");
+
+    VkFormatProperties format_properties;
+    vkGetPhysicalDeviceFormatProperties(gpu(), VK_FORMAT_D32_SFLOAT_S8_UINT, &format_properties);
+    if (!(format_properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+        return;
+    }
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkAttachmentDescription attachment = { 0,
+        VK_FORMAT_D32_SFLOAT_S8_UINT,
+        VK_SAMPLE_COUNT_1_BIT,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+        VK_ATTACHMENT_STORE_OP_DONT_CARE,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
+
+    VkAttachmentReference att_ref = { 0, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL };
+
+    VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 0, nullptr, nullptr, &att_ref, 0, nullptr };
+
+    VkSubpassDependency dep = { 0,
+        0,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+        VK_DEPENDENCY_BY_REGION_BIT};
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 1, &attachment, 1, &subpass, 1, &dep };
+
+    VkResult err;
+    VkRenderPass rp;
+    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    VkImageObj image(m_device);
+    image.init_no_layout(32, 32, VK_FORMAT_D32_SFLOAT_S8_UINT,
+        0x26, // usage
+        VK_IMAGE_TILING_OPTIMAL, 0);
+    ASSERT_TRUE(image.initialized());
+    image.SetLayout(0x6, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+
+    VkImageViewCreateInfo ivci = {
+        VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+        nullptr,
+        0,
+        image.handle(),
+        VK_IMAGE_VIEW_TYPE_2D,
+        VK_FORMAT_D32_SFLOAT_S8_UINT,
+        { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A },
+        { 0x2, 0, 1, 0, 1 },
+    };
+    VkImageView view;
+    err = vkCreateImageView(m_device->device(), &ivci, nullptr, &view);
+    ASSERT_VK_SUCCESS(err);
+
+    VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 1, &view, 32, 32, 1 };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+
+    VkImageMemoryBarrier imb = {};
+    imb.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    imb.pNext = nullptr;
+    imb.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    imb.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+    imb.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    imb.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+    imb.srcQueueFamilyIndex = 0;
+    imb.dstQueueFamilyIndex = 0;
+    imb.image = image.handle();
+    imb.subresourceRange.aspectMask = 0x6;
+    imb.subresourceRange.baseMipLevel = 0;
+    imb.subresourceRange.levelCount = 0x1;
+    imb.subresourceRange.baseArrayLayer = 0;
+    imb.subresourceRange.layerCount = 0x1;
+
+    vkCmdPipelineBarrier(m_commandBuffer->handle(), VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
+        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0, nullptr, 0, nullptr, 1,
+        &imb);
+
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    EndCommandBuffer();
+    QueueCommandBuffer(false);
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyImageView(m_device->device(), view, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, RenderPassTransitionsAttachmentUnused) {
+    TEST_DESCRIPTION("Ensure that layout transitions work correctly without "
+        "errors, when an attachment reference is "
+        "VK_ATTACHMENT_UNUSED");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // A renderpass with no attachments
+    VkAttachmentReference att_ref = { VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
+
+    VkSubpassDescription subpass = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 0, nullptr, 1, &att_ref, nullptr, nullptr, 0, nullptr };
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 0, nullptr, 1, &subpass, 0, nullptr };
+
+    VkRenderPass rp;
+    VkResult err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // A compatible framebuffer.
+    VkFramebufferCreateInfo fci = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, nullptr, 0, rp, 0, nullptr, 32, 32, 1 };
+    VkFramebuffer fb;
+    err = vkCreateFramebuffer(m_device->device(), &fci, nullptr, &fb);
+    ASSERT_VK_SUCCESS(err);
+
+    // Record a command buffer which just begins and ends the renderpass. The
+    // bug manifests in BeginRenderPass.
+    VkRenderPassBeginInfo rpbi = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, nullptr, rp, fb,{ { 0, 0 },{ 32, 32 } }, 0, nullptr };
+    BeginCommandBuffer();
+    vkCmdBeginRenderPass(m_commandBuffer->handle(), &rpbi, VK_SUBPASS_CONTENTS_INLINE);
+    vkCmdEndRenderPass(m_commandBuffer->handle());
+    m_errorMonitor->VerifyNotFound();
+    EndCommandBuffer();
+
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+}
+
+// This is a positive test. No errors are expected.
+TEST_F(VkPositiveLayerTest, StencilLoadOp) {
+    TEST_DESCRIPTION("Create a stencil-only attachment with a LOAD_OP set to "
+        "CLEAR. stencil[Load|Store]Op used to be ignored.");
+    VkResult result = VK_SUCCESS;
+    VkImageFormatProperties formatProps;
+    vkGetPhysicalDeviceImageFormatProperties(gpu(), VK_FORMAT_D24_UNORM_S8_UINT, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL,
+        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
+        &formatProps);
+    if (formatProps.maxExtent.width < 100 || formatProps.maxExtent.height < 100) {
+        return;
+    }
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFormat depth_stencil_fmt = VK_FORMAT_D24_UNORM_S8_UINT;
+    m_depthStencil->Init(m_device, 100, 100, depth_stencil_fmt,
+        VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
+    VkAttachmentDescription att = {};
+    VkAttachmentReference ref = {};
+    att.format = depth_stencil_fmt;
+    att.samples = VK_SAMPLE_COUNT_1_BIT;
+    att.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
+    att.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
+    att.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    att.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+    VkClearValue clear;
+    clear.depthStencil.depth = 1.0;
+    clear.depthStencil.stencil = 0;
+    ref.attachment = 0;
+    ref.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+
+    VkSubpassDescription subpass = {};
+    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
+    subpass.flags = 0;
+    subpass.inputAttachmentCount = 0;
+    subpass.pInputAttachments = NULL;
+    subpass.colorAttachmentCount = 0;
+    subpass.pColorAttachments = NULL;
+    subpass.pResolveAttachments = NULL;
+    subpass.pDepthStencilAttachment = &ref;
+    subpass.preserveAttachmentCount = 0;
+    subpass.pPreserveAttachments = NULL;
+
+    VkRenderPass rp;
+    VkRenderPassCreateInfo rp_info = {};
+    rp_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    rp_info.attachmentCount = 1;
+    rp_info.pAttachments = &att;
+    rp_info.subpassCount = 1;
+    rp_info.pSubpasses = &subpass;
+    result = vkCreateRenderPass(device(), &rp_info, NULL, &rp);
+    ASSERT_VK_SUCCESS(result);
+
+    VkImageView *depthView = m_depthStencil->BindInfo();
+    VkFramebufferCreateInfo fb_info = {};
+    fb_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
+    fb_info.pNext = NULL;
+    fb_info.renderPass = rp;
+    fb_info.attachmentCount = 1;
+    fb_info.pAttachments = depthView;
+    fb_info.width = 100;
+    fb_info.height = 100;
+    fb_info.layers = 1;
+    VkFramebuffer fb;
+    result = vkCreateFramebuffer(device(), &fb_info, NULL, &fb);
+    ASSERT_VK_SUCCESS(result);
+
+    VkRenderPassBeginInfo rpbinfo = {};
+    rpbinfo.clearValueCount = 1;
+    rpbinfo.pClearValues = &clear;
+    rpbinfo.pNext = NULL;
+    rpbinfo.renderPass = rp;
+    rpbinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
+    rpbinfo.renderArea.extent.width = 100;
+    rpbinfo.renderArea.extent.height = 100;
+    rpbinfo.renderArea.offset.x = 0;
+    rpbinfo.renderArea.offset.y = 0;
+    rpbinfo.framebuffer = fb;
+
+    VkFence fence = {};
+    VkFenceCreateInfo fence_ci = {};
+    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fence_ci.pNext = nullptr;
+    fence_ci.flags = 0;
+    result = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fence);
+    ASSERT_VK_SUCCESS(result);
+
+    m_commandBuffer->BeginCommandBuffer();
+    m_commandBuffer->BeginRenderPass(rpbinfo);
+    m_commandBuffer->EndRenderPass();
+    m_commandBuffer->EndCommandBuffer();
+    m_commandBuffer->QueueCommandBuffer(fence);
+
+    VkImageObj destImage(m_device);
+    destImage.init(100, 100, depth_stencil_fmt, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+        VK_IMAGE_TILING_OPTIMAL, 0);
+    VkImageMemoryBarrier barrier = {};
+    VkImageSubresourceRange range;
+    barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+    barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
+    barrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+    barrier.image = m_depthStencil->handle();
+    range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    range.baseMipLevel = 0;
+    range.levelCount = 1;
+    range.baseArrayLayer = 0;
+    range.layerCount = 1;
+    barrier.subresourceRange = range;
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    VkCommandBufferObj cmdbuf(m_device, m_commandPool);
+    cmdbuf.BeginCommandBuffer();
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
+        &barrier);
+    barrier.srcAccessMask = 0;
+    barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+    barrier.image = destImage.handle();
+    barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
+    cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0, nullptr, 1,
+        &barrier);
+    VkImageCopy cregion;
+    cregion.srcSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    cregion.srcSubresource.mipLevel = 0;
+    cregion.srcSubresource.baseArrayLayer = 0;
+    cregion.srcSubresource.layerCount = 1;
+    cregion.srcOffset.x = 0;
+    cregion.srcOffset.y = 0;
+    cregion.srcOffset.z = 0;
+    cregion.dstSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
+    cregion.dstSubresource.mipLevel = 0;
+    cregion.dstSubresource.baseArrayLayer = 0;
+    cregion.dstSubresource.layerCount = 1;
+    cregion.dstOffset.x = 0;
+    cregion.dstOffset.y = 0;
+    cregion.dstOffset.z = 0;
+    cregion.extent.width = 100;
+    cregion.extent.height = 100;
+    cregion.extent.depth = 1;
+    cmdbuf.CopyImage(m_depthStencil->handle(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, destImage.handle(),
+        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cregion);
+    cmdbuf.EndCommandBuffer();
+
+    VkSubmitInfo submit_info;
+    submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+    submit_info.pNext = NULL;
+    submit_info.waitSemaphoreCount = 0;
+    submit_info.pWaitSemaphores = NULL;
+    submit_info.pWaitDstStageMask = NULL;
+    submit_info.commandBufferCount = 1;
+    submit_info.pCommandBuffers = &cmdbuf.handle();
+    submit_info.signalSemaphoreCount = 0;
+    submit_info.pSignalSemaphores = NULL;
+
+    m_errorMonitor->ExpectSuccess();
+    vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    m_errorMonitor->VerifyNotFound();
+
+    vkQueueWaitIdle(m_device->m_queue);
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyFramebuffer(m_device->device(), fb, nullptr);
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, WaitEventThenSet) {
+    TEST_DESCRIPTION("Wait on a event then set it after the wait has been submitted.");
+
+    m_errorMonitor->ExpectSuccess();
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkEvent event;
+    VkEventCreateInfo event_create_info{};
+    event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+    vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer, &begin_info);
+
+        vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, nullptr, 0,
+            nullptr, 0, nullptr);
+        vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+        vkEndCommandBuffer(command_buffer);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer;
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = nullptr;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    { vkSetEvent(m_device->device(), event); }
+
+    vkQueueWaitIdle(queue);
+
+    vkDestroyEvent(m_device->device(), event, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, QueryAndCopySecondaryCommandBuffers) {
+    TEST_DESCRIPTION("Issue a query on a secondary command buffery and copy it on a primary.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkQueryPool query_pool;
+    VkQueryPoolCreateInfo query_pool_create_info{};
+    query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+    query_pool_create_info.queryCount = 1;
+    vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
+
+    VkCommandBuffer secondary_command_buffer;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &secondary_command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    uint32_t qfi = 0;
+    VkBufferCreateInfo buff_create_info = {};
+    buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_create_info.size = 1024;
+    buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    buff_create_info.queueFamilyIndexCount = 1;
+    buff_create_info.pQueueFamilyIndices = &qfi;
+
+    VkResult err;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 1024;
+    mem_alloc.memoryTypeIndex = 0;
+
+    VkMemoryRequirements memReqs;
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
+    bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    VkDeviceMemory mem;
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferInheritanceInfo hinfo = {};
+    hinfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
+    hinfo.renderPass = VK_NULL_HANDLE;
+    hinfo.subpass = 0;
+    hinfo.framebuffer = VK_NULL_HANDLE;
+    hinfo.occlusionQueryEnable = VK_FALSE;
+    hinfo.queryFlags = 0;
+    hinfo.pipelineStatistics = 0;
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        begin_info.pInheritanceInfo = &hinfo;
+        vkBeginCommandBuffer(secondary_command_buffer, &begin_info);
+
+        vkCmdResetQueryPool(secondary_command_buffer, query_pool, 0, 1);
+        vkCmdWriteTimestamp(secondary_command_buffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
+
+        vkEndCommandBuffer(secondary_command_buffer);
+
+        begin_info.pInheritanceInfo = nullptr;
+        vkBeginCommandBuffer(command_buffer, &begin_info);
+
+        vkCmdExecuteCommands(command_buffer, 1, &secondary_command_buffer);
+        vkCmdCopyQueryPoolResults(command_buffer, query_pool, 0, 1, buffer, 0, 0, 0);
+
+        vkEndCommandBuffer(command_buffer);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer;
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = nullptr;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+
+    vkQueueWaitIdle(queue);
+
+    vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &secondary_command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, QueryAndCopyMultipleCommandBuffers) {
+    TEST_DESCRIPTION("Issue a query and copy from it on a second command buffer.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkQueryPool query_pool;
+    VkQueryPoolCreateInfo query_pool_create_info{};
+    query_pool_create_info.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+    query_pool_create_info.queryType = VK_QUERY_TYPE_TIMESTAMP;
+    query_pool_create_info.queryCount = 1;
+    vkCreateQueryPool(m_device->device(), &query_pool_create_info, nullptr, &query_pool);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    uint32_t qfi = 0;
+    VkBufferCreateInfo buff_create_info = {};
+    buff_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+    buff_create_info.size = 1024;
+    buff_create_info.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
+    buff_create_info.queueFamilyIndexCount = 1;
+    buff_create_info.pQueueFamilyIndices = &qfi;
+
+    VkResult err;
+    VkBuffer buffer;
+    err = vkCreateBuffer(m_device->device(), &buff_create_info, NULL, &buffer);
+    ASSERT_VK_SUCCESS(err);
+    VkMemoryAllocateInfo mem_alloc = {};
+    mem_alloc.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+    mem_alloc.pNext = NULL;
+    mem_alloc.allocationSize = 1024;
+    mem_alloc.memoryTypeIndex = 0;
+
+    VkMemoryRequirements memReqs;
+    vkGetBufferMemoryRequirements(m_device->device(), buffer, &memReqs);
+    bool pass = m_device->phy().set_memory_type(memReqs.memoryTypeBits, &mem_alloc, 0);
+    if (!pass) {
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        return;
+    }
+
+    VkDeviceMemory mem;
+    err = vkAllocateMemory(m_device->device(), &mem_alloc, NULL, &mem);
+    ASSERT_VK_SUCCESS(err);
+    err = vkBindBufferMemory(m_device->device(), buffer, mem, 0);
+    ASSERT_VK_SUCCESS(err);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdResetQueryPool(command_buffer[0], query_pool, 0, 1);
+        vkCmdWriteTimestamp(command_buffer[0], VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, query_pool, 0);
+
+        vkEndCommandBuffer(command_buffer[0]);
+
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        vkCmdCopyQueryPoolResults(command_buffer[1], query_pool, 0, 1, buffer, 0, 0, 0);
+
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 2;
+        submit_info.pCommandBuffers = command_buffer;
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = nullptr;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+
+    vkQueueWaitIdle(queue);
+
+    vkDestroyQueryPool(m_device->device(), query_pool, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroyBuffer(m_device->device(), buffer, NULL);
+    vkFreeMemory(m_device->device(), mem, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, ResetEventThenSet) {
+    TEST_DESCRIPTION("Reset an event then set it after the reset has been submitted.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkEvent event;
+    VkEventCreateInfo event_create_info{};
+    event_create_info.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
+    vkCreateEvent(m_device->device(), &event_create_info, nullptr, &event);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer;
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 1;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, &command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer, &begin_info);
+
+        vkCmdResetEvent(command_buffer, event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
+        vkCmdWaitEvents(command_buffer, 1, &event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+        vkEndCommandBuffer(command_buffer);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer;
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = nullptr;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        m_errorMonitor->SetDesiredFailureMsg(VK_DEBUG_REPORT_ERROR_BIT_EXT, "that is already in use by a "
+            "command buffer.");
+        vkSetEvent(m_device->device(), event);
+        m_errorMonitor->VerifyFound();
+    }
+
+    vkQueueWaitIdle(queue);
+
+    vkDestroyEvent(m_device->device(), event, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 1, &command_buffer);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoFencesThreeFrames) {
+    TEST_DESCRIPTION("Two command buffers with two separate fences are each "
+        "run through a Submit & WaitForFences cycle 3 times. This "
+        "previously revealed a bug so running this positive test "
+        "to prevent a regression.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 0, &queue);
+
+    static const uint32_t NUM_OBJECTS = 2;
+    static const uint32_t NUM_FRAMES = 3;
+    VkCommandBuffer cmd_buffers[NUM_OBJECTS] = {};
+    VkFence fences[NUM_OBJECTS] = {};
+
+    VkCommandPool cmd_pool;
+    VkCommandPoolCreateInfo cmd_pool_ci = {};
+    cmd_pool_ci.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    cmd_pool_ci.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    cmd_pool_ci.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    VkResult err = vkCreateCommandPool(m_device->device(), &cmd_pool_ci, nullptr, &cmd_pool);
+    ASSERT_VK_SUCCESS(err);
+
+    VkCommandBufferAllocateInfo cmd_buf_info = {};
+    cmd_buf_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    cmd_buf_info.commandPool = cmd_pool;
+    cmd_buf_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    cmd_buf_info.commandBufferCount = 1;
+
+    VkFenceCreateInfo fence_ci = {};
+    fence_ci.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    fence_ci.pNext = nullptr;
+    fence_ci.flags = 0;
+
+    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
+        err = vkAllocateCommandBuffers(m_device->device(), &cmd_buf_info, &cmd_buffers[i]);
+        ASSERT_VK_SUCCESS(err);
+        err = vkCreateFence(m_device->device(), &fence_ci, nullptr, &fences[i]);
+        ASSERT_VK_SUCCESS(err);
+    }
+
+    for (uint32_t frame = 0; frame < NUM_FRAMES; ++frame) {
+        for (uint32_t obj = 0; obj < NUM_OBJECTS; ++obj) {
+            // Create empty cmd buffer
+            VkCommandBufferBeginInfo cmdBufBeginDesc = {};
+            cmdBufBeginDesc.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+
+            err = vkBeginCommandBuffer(cmd_buffers[obj], &cmdBufBeginDesc);
+            ASSERT_VK_SUCCESS(err);
+            err = vkEndCommandBuffer(cmd_buffers[obj]);
+            ASSERT_VK_SUCCESS(err);
+
+            VkSubmitInfo submit_info = {};
+            submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+            submit_info.commandBufferCount = 1;
+            submit_info.pCommandBuffers = &cmd_buffers[obj];
+            // Submit cmd buffer and wait for fence
+            err = vkQueueSubmit(queue, 1, &submit_info, fences[obj]);
+            ASSERT_VK_SUCCESS(err);
+            err = vkWaitForFences(m_device->device(), 1, &fences[obj], VK_TRUE, UINT64_MAX);
+            ASSERT_VK_SUCCESS(err);
+            err = vkResetFences(m_device->device(), 1, &fences[obj]);
+            ASSERT_VK_SUCCESS(err);
+        }
+    }
+    m_errorMonitor->VerifyNotFound();
+    vkDestroyCommandPool(m_device->device(), cmd_pool, NULL);
+    for (uint32_t i = 0; i < NUM_OBJECTS; ++i) {
+        vkDestroyFence(m_device->device(), fences[i], nullptr);
+    }
+}
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWI) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "submitted on separate queues followed by a QueueWaitIdle.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &semaphore;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &semaphore;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+
+    vkQueueWaitIdle(m_device->m_queue);
+
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceQWIFence) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "submitted on separate queues, the second having a fence"
+        "followed by a QueueWaitIdle.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &semaphore;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &semaphore;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
+    }
+
+    vkQueueWaitIdle(m_device->m_queue);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFenceTwoWFF) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "submitted on separate queues, the second having a fence"
+        "followed by two consecutive WaitForFences calls on the same fence.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &semaphore;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &semaphore;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
+    }
+
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, TwoQueuesEnsureCorrectRetirementWithWorkStolen) {
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2)) {
+        printf("Test requires two queues, skipping\n");
+        return;
+    }
+
+    VkResult err;
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkQueue q0 = m_device->m_queue;
+    VkQueue q1 = nullptr;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &q1);
+    ASSERT_NE(q1, nullptr);
+
+    // An (empty) command buffer. We must have work in the first submission --
+    // the layer treats unfenced work differently from fenced work.
+    VkCommandPoolCreateInfo cpci = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, nullptr, 0, 0 };
+    VkCommandPool pool;
+    err = vkCreateCommandPool(m_device->device(), &cpci, nullptr, &pool);
+    ASSERT_VK_SUCCESS(err);
+    VkCommandBufferAllocateInfo cbai = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, nullptr, pool,
+        VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1 };
+    VkCommandBuffer cb;
+    err = vkAllocateCommandBuffers(m_device->device(), &cbai, &cb);
+    ASSERT_VK_SUCCESS(err);
+    VkCommandBufferBeginInfo cbbi = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, nullptr, 0, nullptr };
+    err = vkBeginCommandBuffer(cb, &cbbi);
+    ASSERT_VK_SUCCESS(err);
+    err = vkEndCommandBuffer(cb);
+    ASSERT_VK_SUCCESS(err);
+
+    // A semaphore
+    VkSemaphoreCreateInfo sci = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0 };
+    VkSemaphore s;
+    err = vkCreateSemaphore(m_device->device(), &sci, nullptr, &s);
+    ASSERT_VK_SUCCESS(err);
+
+    // First submission, to q0
+    VkSubmitInfo s0 = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr, 1, &cb, 1, &s };
+
+    err = vkQueueSubmit(q0, 1, &s0, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Second submission, to q1, waiting on s
+    VkFlags waitmask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; // doesn't really matter what this value is.
+    VkSubmitInfo s1 = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 1, &s, &waitmask, 0, nullptr, 0, nullptr };
+
+    err = vkQueueSubmit(q1, 1, &s1, VK_NULL_HANDLE);
+    ASSERT_VK_SUCCESS(err);
+
+    // Wait for q0 idle
+    err = vkQueueWaitIdle(q0);
+    ASSERT_VK_SUCCESS(err);
+
+    // Command buffer should have been completed (it was on q0); reset the pool.
+    vkFreeCommandBuffers(m_device->device(), pool, 1, &cb);
+
+    m_errorMonitor->VerifyNotFound();
+
+    // Force device completely idle and clean up resources
+    vkDeviceWaitIdle(m_device->device());
+    vkDestroyCommandPool(m_device->device(), pool, nullptr);
+    vkDestroySemaphore(m_device->device(), s, nullptr);
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsSeparateQueuesWithSemaphoreAndOneFence) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "submitted on separate queues, the second having a fence, "
+        "followed by a WaitForFences call.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    if ((m_device->queue_props.empty()) || (m_device->queue_props[0].queueCount < 2))
+        return;
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    VkQueue queue = VK_NULL_HANDLE;
+    vkGetDeviceQueue(m_device->device(), m_device->graphics_queue_node_index_, 1, &queue);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &semaphore;
+        vkQueueSubmit(queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &semaphore;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
+    }
+
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueWithSemaphoreAndOneFence) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "on the same queue, sharing a signal/wait semaphore, the "
+        "second having a fence, "
+        "followed by a WaitForFences call.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 1;
+        submit_info.pSignalSemaphores = &semaphore;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 1;
+        submit_info.pWaitSemaphores = &semaphore;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
+    }
+
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueNullQueueSubmitWithFence) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "on the same queue, no fences, followed by a third QueueSubmit with NO "
+        "SubmitInfos but with a fence, followed by a WaitForFences call.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = VK_NULL_HANDLE;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 0;
+        submit_info.pWaitSemaphores = VK_NULL_HANDLE;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+
+    vkQueueSubmit(m_device->m_queue, 0, NULL, fence);
+
+    VkResult err = vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+    ASSERT_VK_SUCCESS(err);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoQueueSubmitsOneQueueOneFence) {
+
+    TEST_DESCRIPTION("Two command buffers, each in a separate QueueSubmit call "
+        "on the same queue, the second having a fence, followed "
+        "by a WaitForFences call.");
+
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[0];
+        submit_info.signalSemaphoreCount = 0;
+        submit_info.pSignalSemaphores = VK_NULL_HANDLE;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, VK_NULL_HANDLE);
+    }
+    {
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+        VkSubmitInfo submit_info{};
+        submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info.commandBufferCount = 1;
+        submit_info.pCommandBuffers = &command_buffer[1];
+        submit_info.waitSemaphoreCount = 0;
+        submit_info.pWaitSemaphores = VK_NULL_HANDLE;
+        submit_info.pWaitDstStageMask = flags;
+        vkQueueSubmit(m_device->m_queue, 1, &submit_info, fence);
+    }
+
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+// This is a positive test.  No errors should be generated.
+TEST_F(VkPositiveLayerTest, TwoSubmitInfosWithSemaphoreOneQueueSubmitsOneFence) {
+
+    TEST_DESCRIPTION("Two command buffers each in a separate SubmitInfo sent in a single "
+        "QueueSubmit call followed by a WaitForFences call.");
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    m_errorMonitor->ExpectSuccess();
+
+    VkFence fence;
+    VkFenceCreateInfo fence_create_info{};
+    fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+    vkCreateFence(m_device->device(), &fence_create_info, nullptr, &fence);
+
+    VkSemaphore semaphore;
+    VkSemaphoreCreateInfo semaphore_create_info{};
+    semaphore_create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
+    vkCreateSemaphore(m_device->device(), &semaphore_create_info, nullptr, &semaphore);
+
+    VkCommandPool command_pool;
+    VkCommandPoolCreateInfo pool_create_info{};
+    pool_create_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+    pool_create_info.queueFamilyIndex = m_device->graphics_queue_node_index_;
+    pool_create_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+    vkCreateCommandPool(m_device->device(), &pool_create_info, nullptr, &command_pool);
+
+    VkCommandBuffer command_buffer[2];
+    VkCommandBufferAllocateInfo command_buffer_allocate_info{};
+    command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+    command_buffer_allocate_info.commandPool = command_pool;
+    command_buffer_allocate_info.commandBufferCount = 2;
+    command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+    vkAllocateCommandBuffers(m_device->device(), &command_buffer_allocate_info, command_buffer);
+
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[0], &begin_info);
+
+        vkCmdPipelineBarrier(command_buffer[0], VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0,
+            nullptr, 0, nullptr, 0, nullptr);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[0], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[0]);
+    }
+    {
+        VkCommandBufferBeginInfo begin_info{};
+        begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+        vkBeginCommandBuffer(command_buffer[1], &begin_info);
+
+        VkViewport viewport{};
+        viewport.maxDepth = 1.0f;
+        viewport.minDepth = 0.0f;
+        viewport.width = 512;
+        viewport.height = 512;
+        viewport.x = 0;
+        viewport.y = 0;
+        vkCmdSetViewport(command_buffer[1], 0, 1, &viewport);
+        vkEndCommandBuffer(command_buffer[1]);
+    }
+    {
+        VkSubmitInfo submit_info[2];
+        VkPipelineStageFlags flags[]{ VK_PIPELINE_STAGE_ALL_COMMANDS_BIT };
+
+        submit_info[0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info[0].pNext = NULL;
+        submit_info[0].commandBufferCount = 1;
+        submit_info[0].pCommandBuffers = &command_buffer[0];
+        submit_info[0].signalSemaphoreCount = 1;
+        submit_info[0].pSignalSemaphores = &semaphore;
+        submit_info[0].waitSemaphoreCount = 0;
+        submit_info[0].pWaitSemaphores = NULL;
+        submit_info[0].pWaitDstStageMask = 0;
+
+        submit_info[1].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+        submit_info[1].pNext = NULL;
+        submit_info[1].commandBufferCount = 1;
+        submit_info[1].pCommandBuffers = &command_buffer[1];
+        submit_info[1].waitSemaphoreCount = 1;
+        submit_info[1].pWaitSemaphores = &semaphore;
+        submit_info[1].pWaitDstStageMask = flags;
+        submit_info[1].signalSemaphoreCount = 0;
+        submit_info[1].pSignalSemaphores = NULL;
+        vkQueueSubmit(m_device->m_queue, 2, &submit_info[0], fence);
+    }
+
+    vkWaitForFences(m_device->device(), 1, &fence, VK_TRUE, UINT64_MAX);
+
+    vkDestroyFence(m_device->device(), fence, nullptr);
+    vkFreeCommandBuffers(m_device->device(), command_pool, 2, &command_buffer[0]);
+    vkDestroyCommandPool(m_device->device(), command_pool, NULL);
+    vkDestroySemaphore(m_device->device(), semaphore, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, RenderPassSecondaryCommandBuffersMultipleTimes) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    BeginCommandBuffer();                                   // Framework implicitly begins the renderpass.
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle()); // End implicit.
+
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
+    m_errorMonitor->VerifyNotFound();
+    vkCmdBeginRenderPass(m_commandBuffer->GetBufferHandle(), &m_renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+    m_errorMonitor->VerifyNotFound();
+    vkCmdEndRenderPass(m_commandBuffer->GetBufferHandle());
+    m_errorMonitor->VerifyNotFound();
+
+    m_commandBuffer->EndCommandBuffer();
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, ValidRenderPassAttachmentLayoutWithLoadOp) {
+    TEST_DESCRIPTION("Positive test where we create a renderpass with an "
+                     "attachment that uses LOAD_OP_CLEAR, the first subpass "
+                     "has a valid layout, and a second subpass then uses a "
+                     "valid *READ_ONLY* layout.");
+    m_errorMonitor->ExpectSuccess();
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkAttachmentReference attach[2] = {};
+    attach[0].attachment = 0;
+    attach[0].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    attach[1].attachment = 0;
+    attach[1].layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+    VkSubpassDescription subpasses[2] = {};
+    // First subpass clears DS attach on load
+    subpasses[0].pDepthStencilAttachment = &attach[0];
+    // 2nd subpass reads in DS as input attachment
+    subpasses[1].inputAttachmentCount = 1;
+    subpasses[1].pInputAttachments = &attach[1];
+    VkAttachmentDescription attach_desc = {};
+    attach_desc.format = VK_FORMAT_D24_UNORM_S8_UINT;
+    attach_desc.samples = VK_SAMPLE_COUNT_1_BIT;
+    attach_desc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
+    attach_desc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
+    attach_desc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    attach_desc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+    attach_desc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
+    attach_desc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
+    VkRenderPassCreateInfo rpci = {};
+    rpci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
+    rpci.attachmentCount = 1;
+    rpci.pAttachments = &attach_desc;
+    rpci.subpassCount = 2;
+    rpci.pSubpasses = subpasses;
+
+    // Now create RenderPass and verify no errors
+    VkRenderPass rp;
+    vkCreateRenderPass(m_device->device(), &rpci, NULL, &rp);
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyRenderPass(m_device->device(), rp, NULL);
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineAttribMatrixType) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts matrices passed "
+        "as vertex attributes");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkVertexInputBindingDescription input_binding;
+    memset(&input_binding, 0, sizeof(input_binding));
+
+    VkVertexInputAttributeDescription input_attribs[2];
+    memset(input_attribs, 0, sizeof(input_attribs));
+
+    for (int i = 0; i < 2; i++) {
+        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+        input_attribs[i].location = i;
+    }
+
+    char const *vsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) in mat2x4 x;\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = x[0] + x[1];\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(&input_binding, 1);
+    pipe.AddVertexInputAttribs(input_attribs, 2);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    /* expect success */
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineAttribArrayType) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkVertexInputBindingDescription input_binding;
+    memset(&input_binding, 0, sizeof(input_binding));
+
+    VkVertexInputAttributeDescription input_attribs[2];
+    memset(input_attribs, 0, sizeof(input_attribs));
+
+    for (int i = 0; i < 2; i++) {
+        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+        input_attribs[i].location = i;
+    }
+
+    char const *vsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) in vec4 x[2];\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = x[0] + x[1];\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(&input_binding, 1);
+    pipe.AddVertexInputAttribs(input_attribs, 2);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineAttribComponents) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts consuming a vertex attribute "
+        "through multiple vertex shader inputs, each consuming a different "
+        "subset of the components.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkVertexInputBindingDescription input_binding;
+    memset(&input_binding, 0, sizeof(input_binding));
+
+    VkVertexInputAttributeDescription input_attribs[3];
+    memset(input_attribs, 0, sizeof(input_attribs));
+
+    for (int i = 0; i < 3; i++) {
+        input_attribs[i].format = VK_FORMAT_R32G32B32A32_SFLOAT;
+        input_attribs[i].location = i;
+    }
+
+    char const *vsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) in vec4 x;\n"
+        "layout(location=1) in vec3 y1;\n"
+        "layout(location=1, component=3) in float y2;\n"
+        "layout(location=2) in vec4 z;\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = x + vec4(y1, y2) + z;\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(&input_binding, 1);
+    pipe.AddVertexInputAttribs(input_attribs, 3);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineSimplePositive) {
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    char const *vsSource = "#version 450\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = vec4(0);\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineRelaxedTypeMatch) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts the relaxed type matching rules "
+        "set out in 14.1.3: fundamental type must match, and producer side must "
+        "have at least as many components");
+    m_errorMonitor->ExpectSuccess();
+
+    // VK 1.0.8 Specification, 14.1.3 "Additionally,..." block
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    char const *vsSource = "#version 450\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "layout(location=0) out vec3 x;\n"
+        "layout(location=1) out ivec3 y;\n"
+        "layout(location=2) out vec3 z;\n"
+        "void main(){\n"
+        "   gl_Position = vec4(0);\n"
+        "   x = vec3(0); y = ivec3(0); z = vec3(0);\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "layout(location=0) in float x;\n"
+        "layout(location=1) flat in int y;\n"
+        "layout(location=2) in vec2 z;\n"
+        "void main(){\n"
+        "   color = vec4(1 + x + y + z.x);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkResult err = VK_SUCCESS;
+    err = pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+    ASSERT_VK_SUCCESS(err);
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineTessPerVertex) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts per-vertex variables "
+        "passed between the TCS and TES stages");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    if (!m_device->phy().features().tessellationShader) {
+        printf("Device does not support tessellation shaders; skipped.\n");
+        return;
+    }
+
+    char const *vsSource = "#version 450\n"
+        "void main(){}\n";
+    char const *tcsSource = "#version 450\n"
+        "layout(location=0) out int x[];\n"
+        "layout(vertices=3) out;\n"
+        "void main(){\n"
+        "   gl_TessLevelOuter[0] = gl_TessLevelOuter[1] = gl_TessLevelOuter[2] = 1;\n"
+        "   gl_TessLevelInner[0] = 1;\n"
+        "   x[gl_InvocationID] = gl_InvocationID;\n"
+        "}\n";
+    char const *tesSource = "#version 450\n"
+        "layout(triangles, equal_spacing, cw) in;\n"
+        "layout(location=0) in int x[];\n"
+        "out gl_PerVertex { vec4 gl_Position; };\n"
+        "void main(){\n"
+        "   gl_Position.xyz = gl_TessCoord;\n"
+        "   gl_Position.w = x[0] + x[1] + x[2];\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj tcs(m_device, tcsSource, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, this);
+    VkShaderObj tes(m_device, tesSource, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineInputAssemblyStateCreateInfo iasci{ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, nullptr, 0,
+        VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, VK_FALSE };
+
+    VkPipelineTessellationStateCreateInfo tsci{ VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, nullptr, 0, 3 };
+
+    VkPipelineObj pipe(m_device);
+    pipe.SetInputAssembly(&iasci);
+    pipe.SetTessellation(&tsci);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&tcs);
+    pipe.AddShader(&tes);
+    pipe.AddShader(&fs);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineGeometryInputBlockPositive) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a user-defined "
+        "interface block passed into the geometry shader. This "
+        "is interesting because the 'extra' array level is not "
+        "present on the member type, but on the block instance.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    if (!m_device->phy().features().geometryShader) {
+        printf("Device does not support geometry shaders; skipped.\n");
+        return;
+    }
+
+    char const *vsSource = "#version 450\n"
+        "layout(location=0) out VertexData { vec4 x; } vs_out;\n"
+        "void main(){\n"
+        "   vs_out.x = vec4(1);\n"
+        "}\n";
+    char const *gsSource = "#version 450\n"
+        "layout(triangles) in;\n"
+        "layout(triangle_strip, max_vertices=3) out;\n"
+        "layout(location=0) in VertexData { vec4 x; } gs_in[];\n"
+        "out gl_PerVertex { vec4 gl_Position; };\n"
+        "void main() {\n"
+        "   gl_Position = gs_in[0].x;\n"
+        "   EmitVertex();\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj gs(m_device, gsSource, VK_SHADER_STAGE_GEOMETRY_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&gs);
+    pipe.AddShader(&fs);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipeline64BitAttributesPositive) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts basic use of 64bit vertex "
+        "attributes. This is interesting because they consume multiple "
+        "locations.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    if (!m_device->phy().features().shaderFloat64) {
+        printf("Device does not support 64bit vertex attributes; skipped.\n");
+        return;
+    }
+
+    VkVertexInputBindingDescription input_bindings[1];
+    memset(input_bindings, 0, sizeof(input_bindings));
+
+    VkVertexInputAttributeDescription input_attribs[4];
+    memset(input_attribs, 0, sizeof(input_attribs));
+    input_attribs[0].location = 0;
+    input_attribs[0].offset = 0;
+    input_attribs[0].format = VK_FORMAT_R64G64B64A64_SFLOAT;
+    input_attribs[1].location = 2;
+    input_attribs[1].offset = 32;
+    input_attribs[1].format = VK_FORMAT_R64G64B64A64_SFLOAT;
+    input_attribs[2].location = 4;
+    input_attribs[2].offset = 64;
+    input_attribs[2].format = VK_FORMAT_R64G64B64A64_SFLOAT;
+    input_attribs[3].location = 6;
+    input_attribs[3].offset = 96;
+    input_attribs[3].format = VK_FORMAT_R64G64B64A64_SFLOAT;
+
+    char const *vsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) in dmat4 x;\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "   gl_Position = vec4(x[0][0]);\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main(){\n"
+        "   color = vec4(1);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddColorAttachment();
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+
+    pipe.AddVertexInputBindings(input_bindings, 1);
+    pipe.AddVertexInputAttribs(input_attribs, 4);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.AppendDummy();
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    pipe.CreateVKPipeline(descriptorSet.GetPipelineLayout(), renderPass());
+
+    m_errorMonitor->VerifyNotFound();
+}
+
+TEST_F(VkPositiveLayerTest, CreatePipelineInputAttachmentPositive) {
+    TEST_DESCRIPTION("Positive test for a correctly matched input attachment");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    char const *vsSource = "#version 450\n"
+        "\n"
+        "out gl_PerVertex {\n"
+        "    vec4 gl_Position;\n"
+        "};\n"
+        "void main(){\n"
+        "    gl_Position = vec4(1);\n"
+        "}\n";
+    char const *fsSource = "#version 450\n"
+        "\n"
+        "layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput x;\n"
+        "layout(location=0) out vec4 color;\n"
+        "void main() {\n"
+        "   color = subpassLoad(x);\n"
+        "}\n";
+
+    VkShaderObj vs(m_device, vsSource, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(m_device, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    VkPipelineObj pipe(m_device);
+    pipe.AddShader(&vs);
+    pipe.AddShader(&fs);
+    pipe.AddColorAttachment();
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkDescriptorSetLayoutBinding dslb = { 0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr };
+    VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dslb };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkAttachmentDescription descs[2] = {
+        { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL },
+        { 0, VK_FORMAT_R8G8B8A8_UNORM, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
+        VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL },
+    };
+    VkAttachmentReference color = {
+        0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+    };
+    VkAttachmentReference input = {
+        1, VK_IMAGE_LAYOUT_GENERAL,
+    };
+
+    VkSubpassDescription sd = { 0, VK_PIPELINE_BIND_POINT_GRAPHICS, 1, &input, 1, &color, nullptr, nullptr, 0, nullptr };
+
+    VkRenderPassCreateInfo rpci = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, nullptr, 0, 2, descs, 1, &sd, 0, nullptr };
+    VkRenderPass rp;
+    err = vkCreateRenderPass(m_device->device(), &rpci, nullptr, &rp);
+    ASSERT_VK_SUCCESS(err);
+
+    // should be OK. would go wrong here if it's going to...
+    pipe.CreateVKPipeline(pl, rp);
+
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyRenderPass(m_device->device(), rp, nullptr);
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, CreateComputePipelineMissingDescriptorUnusedPositive) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a compute pipeline which declares a "
+        "descriptor-backed resource which is not provided, but the shader does not "
+        "statically use it. This is interesting because it requires compute pipelines "
+        "to have a proper descriptor use walk, which they didn't for some time.");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    char const *csSource = "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) buffer block { vec4 x; };\n"
+        "void main(){\n"
+        "   // x is not used.\n"
+        "}\n";
+
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkDescriptorSetObj descriptorSet(m_device);
+    descriptorSet.CreateVKDescriptorSet(m_commandBuffer);
+
+    VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr,
+        0,
+        { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
+        VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr },
+        descriptorSet.GetPipelineLayout(),
+        VK_NULL_HANDLE,
+        -1 };
+
+    VkPipeline pipe;
+    VkResult err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+}
+
+TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsSampler) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
+        "sampler portion of a combined image + sampler");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+        { 1, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+        { 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource = "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform sampler s;\n"
+        "layout(set=0, binding=1) uniform texture2D t;\n"
+        "layout(set=0, binding=2) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr,
+        0,
+        { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
+        VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr },
+        pl,
+        VK_NULL_HANDLE,
+        -1 };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsImage) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming only the "
+        "image portion of a combined image + sampler");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+        { 1, VK_DESCRIPTOR_TYPE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+        { 2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 3, bindings };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource = "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform texture2D t;\n"
+        "layout(set=0, binding=1) uniform sampler s;\n"
+        "layout(set=0, binding=2) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr,
+        0,
+        { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
+        VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr },
+        pl,
+        VK_NULL_HANDLE,
+        -1 };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, CreateComputePipelineCombinedImageSamplerConsumedAsBoth) {
+    TEST_DESCRIPTION("Test that pipeline validation accepts a shader consuming "
+        "both the sampler and the image of a combined image+sampler "
+        "but via separate variables");
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    VkDescriptorSetLayoutBinding bindings[] = {
+        { 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+        { 1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1, VK_SHADER_STAGE_COMPUTE_BIT, nullptr },
+    };
+    VkDescriptorSetLayoutCreateInfo dslci = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, nullptr, 0, 2, bindings };
+    VkDescriptorSetLayout dsl;
+    VkResult err = vkCreateDescriptorSetLayout(m_device->device(), &dslci, nullptr, &dsl);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineLayoutCreateInfo plci = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, nullptr, 0, 1, &dsl, 0, nullptr };
+    VkPipelineLayout pl;
+    err = vkCreatePipelineLayout(m_device->device(), &plci, nullptr, &pl);
+    ASSERT_VK_SUCCESS(err);
+
+    char const *csSource = "#version 450\n"
+        "\n"
+        "layout(local_size_x=1) in;\n"
+        "layout(set=0, binding=0) uniform texture2D t;\n"
+        "layout(set=0, binding=0) uniform sampler s;  // both binding 0!\n"
+        "layout(set=0, binding=1) buffer block { vec4 x; };\n"
+        "void main() {\n"
+        "   x = texture(sampler2D(t, s), vec2(0));\n"
+        "}\n";
+    VkShaderObj cs(m_device, csSource, VK_SHADER_STAGE_COMPUTE_BIT, this);
+
+    VkComputePipelineCreateInfo cpci = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
+        nullptr,
+        0,
+        { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, nullptr, 0,
+        VK_SHADER_STAGE_COMPUTE_BIT, cs.handle(), "main", nullptr },
+        pl,
+        VK_NULL_HANDLE,
+        -1 };
+
+    VkPipeline pipe;
+    err = vkCreateComputePipelines(m_device->device(), VK_NULL_HANDLE, 1, &cpci, nullptr, &pipe);
+
+    m_errorMonitor->VerifyNotFound();
+
+    if (err == VK_SUCCESS) {
+        vkDestroyPipeline(m_device->device(), pipe, nullptr);
+    }
+
+    vkDestroyPipelineLayout(m_device->device(), pl, nullptr);
+    vkDestroyDescriptorSetLayout(m_device->device(), dsl, nullptr);
+}
+
+TEST_F(VkPositiveLayerTest, ValidStructPNext) {
+    TEST_DESCRIPTION("Verify that a valid pNext value is handled correctly");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+
+    // Positive test to check parameter_validation and unique_objects support
+    // for NV_dedicated_allocation
+    uint32_t extension_count = 0;
+    bool supports_nv_dedicated_allocation = false;
+    VkResult err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, nullptr);
+    ASSERT_VK_SUCCESS(err);
+
+    if (extension_count > 0) {
+        std::vector<VkExtensionProperties> available_extensions(extension_count);
+
+        err = vkEnumerateDeviceExtensionProperties(gpu(), nullptr, &extension_count, &available_extensions[0]);
+        ASSERT_VK_SUCCESS(err);
+
+        for (const auto &extension_props : available_extensions) {
+            if (strcmp(extension_props.extensionName, VK_NV_DEDICATED_ALLOCATION_EXTENSION_NAME) == 0) {
+                supports_nv_dedicated_allocation = true;
+            }
+        }
+    }
+
+    if (supports_nv_dedicated_allocation) {
+        m_errorMonitor->ExpectSuccess();
+
+        VkDedicatedAllocationBufferCreateInfoNV dedicated_buffer_create_info = {};
+        dedicated_buffer_create_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV;
+        dedicated_buffer_create_info.pNext = nullptr;
+        dedicated_buffer_create_info.dedicatedAllocation = VK_TRUE;
+
+        uint32_t queue_family_index = 0;
+        VkBufferCreateInfo buffer_create_info = {};
+        buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+        buffer_create_info.pNext = &dedicated_buffer_create_info;
+        buffer_create_info.size = 1024;
+        buffer_create_info.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+        buffer_create_info.queueFamilyIndexCount = 1;
+        buffer_create_info.pQueueFamilyIndices = &queue_family_index;
+
+        VkBuffer buffer;
+        VkResult err = vkCreateBuffer(m_device->device(), &buffer_create_info, NULL, &buffer);
+        ASSERT_VK_SUCCESS(err);
+
+        VkMemoryRequirements memory_reqs;
+        vkGetBufferMemoryRequirements(m_device->device(), buffer, &memory_reqs);
+
+        VkDedicatedAllocationMemoryAllocateInfoNV dedicated_memory_info = {};
+        dedicated_memory_info.sType = VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV;
+        dedicated_memory_info.pNext = nullptr;
+        dedicated_memory_info.buffer = buffer;
+        dedicated_memory_info.image = VK_NULL_HANDLE;
+
+        VkMemoryAllocateInfo memory_info = {};
+        memory_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+        memory_info.pNext = &dedicated_memory_info;
+        memory_info.allocationSize = memory_reqs.size;
+
+        bool pass;
+        pass = m_device->phy().set_memory_type(memory_reqs.memoryTypeBits, &memory_info, 0);
+        ASSERT_TRUE(pass);
+
+        VkDeviceMemory buffer_memory;
+        err = vkAllocateMemory(m_device->device(), &memory_info, NULL, &buffer_memory);
+        ASSERT_VK_SUCCESS(err);
+
+        err = vkBindBufferMemory(m_device->device(), buffer, buffer_memory, 0);
+        ASSERT_VK_SUCCESS(err);
+
+        vkDestroyBuffer(m_device->device(), buffer, NULL);
+        vkFreeMemory(m_device->device(), buffer_memory, NULL);
+
+        m_errorMonitor->VerifyNotFound();
+    }
+}
+
+TEST_F(VkPositiveLayerTest, PSOPolygonModeValid) {
+    VkResult err;
+
+    TEST_DESCRIPTION("Verify that using a solid polygon fill mode works correctly.");
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    std::vector<const char *> device_extension_names;
+    auto features = m_device->phy().features();
+    // Artificially disable support for non-solid fill modes
+    features.fillModeNonSolid = false;
+    // The sacrificial device object
+    VkDeviceObj test_device(0, gpu(), device_extension_names, &features);
+
+    VkRenderpassObj render_pass(&test_device);
+
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.setLayoutCount = 0;
+    pipeline_layout_ci.pSetLayouts = NULL;
+
+    VkPipelineLayout pipeline_layout;
+    err = vkCreatePipelineLayout(test_device.device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+
+    VkPipelineRasterizationStateCreateInfo rs_ci = {};
+    rs_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
+    rs_ci.pNext = nullptr;
+    rs_ci.lineWidth = 1.0f;
+    rs_ci.rasterizerDiscardEnable = true;
+
+    VkShaderObj vs(&test_device, bindStateVertShaderText, VK_SHADER_STAGE_VERTEX_BIT, this);
+    VkShaderObj fs(&test_device, bindStateFragShaderText, VK_SHADER_STAGE_FRAGMENT_BIT, this);
+
+    // Set polygonMode=FILL. No error is expected
+    m_errorMonitor->ExpectSuccess();
+    {
+        VkPipelineObj pipe(&test_device);
+        pipe.AddShader(&vs);
+        pipe.AddShader(&fs);
+        pipe.AddColorAttachment();
+        // Set polygonMode to a good value
+        rs_ci.polygonMode = VK_POLYGON_MODE_FILL;
+        pipe.SetRasterization(&rs_ci);
+        pipe.CreateVKPipeline(pipeline_layout, render_pass.handle());
+    }
+    m_errorMonitor->VerifyNotFound();
+
+    vkDestroyPipelineLayout(test_device.device(), pipeline_layout, NULL);
+}
+
+TEST_F(VkPositiveLayerTest, ValidPushConstants) {
+    VkResult err;
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    ASSERT_NO_FATAL_FAILURE(InitViewport());
+    ASSERT_NO_FATAL_FAILURE(InitRenderTarget());
+
+    VkPipelineLayout pipeline_layout;
+    VkPushConstantRange pc_range = {};
+    VkPipelineLayoutCreateInfo pipeline_layout_ci = {};
+    pipeline_layout_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+    pipeline_layout_ci.pushConstantRangeCount = 1;
+    pipeline_layout_ci.pPushConstantRanges = &pc_range;
+
+    //
+    // Check for invalid push constant ranges in pipeline layouts.
+    //
+    struct PipelineLayoutTestCase {
+        VkPushConstantRange const range;
+        char const *msg;
+    };
+
+    // Check for overlapping ranges
+    const uint32_t ranges_per_test = 5;
+    struct OverlappingRangeTestCase {
+        VkPushConstantRange const ranges[ranges_per_test];
+        char const *msg;
+    };
+
+    // Run some positive tests to make sure overlap checking in the layer is OK
+    const std::array<OverlappingRangeTestCase, 2> overlapping_range_tests_pos = { { { { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 },
+    { VK_SHADER_STAGE_VERTEX_BIT, 4, 4 },
+    { VK_SHADER_STAGE_VERTEX_BIT, 8, 4 },
+    { VK_SHADER_STAGE_VERTEX_BIT, 12, 4 },
+    { VK_SHADER_STAGE_VERTEX_BIT, 16, 4 } },
+        "" },
+        { { { VK_SHADER_STAGE_VERTEX_BIT, 92, 24 },
+        { VK_SHADER_STAGE_VERTEX_BIT, 80, 4 },
+        { VK_SHADER_STAGE_VERTEX_BIT, 64, 8 },
+        { VK_SHADER_STAGE_VERTEX_BIT, 4, 16 },
+        { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 } },
+        "" } } };
+    for (const auto &iter : overlapping_range_tests_pos) {
+        pipeline_layout_ci.pPushConstantRanges = iter.ranges;
+        m_errorMonitor->ExpectSuccess();
+        err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+        m_errorMonitor->VerifyNotFound();
+        if (VK_SUCCESS == err) {
+            vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+        }
+    }
+
+    //
+    // CmdPushConstants tests
+    //
+    const uint8_t dummy_values[100] = {};
+
+    BeginCommandBuffer();
+
+    // positive overlapping range tests with cmd
+    const std::array<PipelineLayoutTestCase, 4> cmd_overlap_tests_pos = { {
+        { { VK_SHADER_STAGE_VERTEX_BIT, 0, 16 }, "" },
+        { { VK_SHADER_STAGE_VERTEX_BIT, 0, 4 }, "" },
+        { { VK_SHADER_STAGE_VERTEX_BIT, 20, 12 }, "" },
+        { { VK_SHADER_STAGE_VERTEX_BIT, 56, 36 }, "" },
+        } };
+
+    // Setup ranges: [0,16) [20,36) [36,44) [44,52) [56,80) [80,92)
+    const VkPushConstantRange pc_range4[] = {
+        { VK_SHADER_STAGE_VERTEX_BIT, 20, 16 },{ VK_SHADER_STAGE_VERTEX_BIT, 0, 16 },{ VK_SHADER_STAGE_VERTEX_BIT, 44, 8 },
+        { VK_SHADER_STAGE_VERTEX_BIT, 80, 12 },{ VK_SHADER_STAGE_VERTEX_BIT, 36, 8 },{ VK_SHADER_STAGE_VERTEX_BIT, 56, 24 },
+    };
+
+    pipeline_layout_ci.pushConstantRangeCount = sizeof(pc_range4) / sizeof(VkPushConstantRange);
+    pipeline_layout_ci.pPushConstantRanges = pc_range4;
+    err = vkCreatePipelineLayout(m_device->device(), &pipeline_layout_ci, NULL, &pipeline_layout);
+    ASSERT_VK_SUCCESS(err);
+    for (const auto &iter : cmd_overlap_tests_pos) {
+        m_errorMonitor->ExpectSuccess();
+        vkCmdPushConstants(m_commandBuffer->GetBufferHandle(), pipeline_layout, iter.range.stageFlags, iter.range.offset,
+            iter.range.size, dummy_values);
+        m_errorMonitor->VerifyNotFound();
+    }
+    vkDestroyPipelineLayout(m_device->device(), pipeline_layout, NULL);
+
+    EndCommandBuffer();
+}
+
+
+
+
+
+
+
+#if 0 // A few devices have issues with this test so disabling for now
+TEST_F(VkPositiveLayerTest, LongFenceChain)
+{
+    m_errorMonitor->ExpectSuccess();
+
+    ASSERT_NO_FATAL_FAILURE(InitState());
+    VkResult err;
+
+    std::vector<VkFence> fences;
+
+    const int chainLength = 32768;
+
+    for (int i = 0; i < chainLength; i++) {
+        VkFenceCreateInfo fci = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, nullptr, 0 };
+        VkFence fence;
+        err = vkCreateFence(m_device->device(), &fci, nullptr, &fence);
+        ASSERT_VK_SUCCESS(err);
+
+        fences.push_back(fence);
+
+        VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO, nullptr, 0, nullptr, nullptr,
+            0, nullptr, 0, nullptr };
+        err = vkQueueSubmit(m_device->m_queue, 1, &si, fence);
+        ASSERT_VK_SUCCESS(err);
+
+    }
+
+    // BOOM, stack overflow.
+    vkWaitForFences(m_device->device(), 1, &fences.back(), VK_TRUE, UINT64_MAX);
+
+    for (auto fence : fences)
+        vkDestroyFence(m_device->device(), fence, nullptr);
+
+    m_errorMonitor->VerifyNotFound();
+}
+#endif
+
+
 #if defined(ANDROID) && defined(VALIDATION_APK)
 static bool initialized = false;
 static bool active = false;
diff --git a/tests/layers/CMakeLists.txt b/tests/layers/CMakeLists.txt
index d18580b..ac16e36 100644
--- a/tests/layers/CMakeLists.txt
+++ b/tests/layers/CMakeLists.txt
@@ -21,6 +21,7 @@
                 COMMAND copy ${src_json} ${dst_json}
                 VERBATIM
                 )
+                add_dependencies(${config_file}-json ${config_file})
         endforeach(config_file)
     endif()
 else()
@@ -42,15 +43,13 @@
         DEPENDS ${PROJECT_SOURCE_DIR}/vk-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py
     )
     add_library(VkLayer_${target} SHARED ${ARGN} VkLayer_${target}.def)
-    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
-    set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/VkLayer_${target}.def")
+    add_dependencies(VkLayer_${target} generate_tests_dispatch_table_helper VkLayer_utils)
     endmacro()
 else()
     macro(add_vk_layer target)
     add_library(VkLayer_${target} SHARED ${ARGN})
-    add_dependencies(VkLayer_${target} generate_vk_layer_helpers)
+    add_dependencies(VkLayer_${target} generate_tests_dispatch_table_helper VkLayer_utils)
     set_target_properties(VkLayer_${target} PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic")
-    install(TARGETS VkLayer_${target} DESTINATION ${PROJECT_BINARY_DIR}/install_staging)
     endmacro()
 endif()
 
@@ -59,6 +58,7 @@
     ${CMAKE_CURRENT_SOURCE_DIR}/../../layers
     ${CMAKE_CURRENT_SOURCE_DIR}/../../loader
     ${CMAKE_CURRENT_SOURCE_DIR}/../../include/vulkan
+    ${CMAKE_CURRENT_BINARY_DIR}
     ${CMAKE_CURRENT_BINARY_DIR}/../../layers
 )
 
@@ -68,14 +68,18 @@
     set (CMAKE_CXX_FLAGS_DEBUG   "${CMAKE_CXX_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
     set (CMAKE_C_FLAGS_DEBUG     "${CMAKE_C_FLAGS_DEBUG} -D_CRT_SECURE_NO_WARNINGS /bigobj")
 else()
-    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpointer-arith -Wno-unused-function -fvisibility=default")
-    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wno-unused-function -fvisibility=default")
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpointer-arith -Wno-unused-function")
+    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wno-unused-function")
 endif()
 
 add_custom_command(OUTPUT vk_dispatch_table_helper.h
     COMMAND ${PYTHON_CMD} ${PROJECT_SOURCE_DIR}/vk-generate.py ${DisplayServer} dispatch-table-ops layer > vk_dispatch_table_helper.h
     DEPENDS ${PROJECT_SOURCE_DIR}/vk-generate.py ${PROJECT_SOURCE_DIR}/vulkan.py)
 
+add_custom_target(generate_tests_dispatch_table_helper DEPENDS
+    vk_dispatch_table_helper.h
+)
+
 set (WRAP_SRCS
        wrap_objects.cpp
 	   ${CMAKE_CURRENT_SOURCE_DIR}/../../layers/vk_layer_table.cpp
diff --git a/tests/run_loader_tests.sh b/tests/run_loader_tests.sh
index c640bbe..87107b4 100755
--- a/tests/run_loader_tests.sh
+++ b/tests/run_loader_tests.sh
@@ -83,6 +83,6 @@
 RunEnumerateInstanceExtensionPropertiesTest
 
 # Test the wrap objects layer.
-./run_wrap_objects_tests.sh
+./run_wrap_objects_tests.sh || exit 1
 
 popd > /dev/null
diff --git a/tests/run_wrap_objects_tests.sh b/tests/run_wrap_objects_tests.sh
index 152cd32..d1b43ad 100755
--- a/tests/run_wrap_objects_tests.sh
+++ b/tests/run_wrap_objects_tests.sh
@@ -111,14 +111,15 @@
 echo "Middle insertion test PASSED"
 
 # Run the layer validation tests with and without the wrap-objects layer. Diff the results.
-diff \
-   <(GTEST_PRINT_TIME=0 \
-      ./vk_layer_validation_tests) \
-   <(GTEST_PRINT_TIME=0 \
-      VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
-      LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
-      VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_wrap_objects \
-      ./vk_layer_validation_tests)
+# Filter out the "Unexpected:" lines because they contain varying object handles.
+GTEST_PRINT_TIME=0 \
+   ./vk_layer_validation_tests | grep -v "^Unexpected: " > unwrapped.out
+GTEST_PRINT_TIME=0 \
+   VK_LAYER_PATH=$VK_LAYER_PATH:`pwd`/layers \
+   LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/layers \
+   VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_wrap_objects \
+   ./vk_layer_validation_tests | grep -v "^Unexpected: " > wrapped.out
+diff unwrapped.out wrapped.out
 ec=$?
 
 if [ $ec -eq 1 ]
diff --git a/tests/vkrenderframework.cpp b/tests/vkrenderframework.cpp
index c074889..78df418 100644
--- a/tests/vkrenderframework.cpp
+++ b/tests/vkrenderframework.cpp
@@ -269,7 +269,7 @@
     att.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
     att.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
     att.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
-    att.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+    att.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
     att.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
 
     VkAttachmentReference ref = {};
diff --git a/threading_generator.py b/threading_generator.py
new file mode 100644
index 0000000..0d0df12
--- /dev/null
+++ b/threading_generator.py
@@ -0,0 +1,467 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2016 The Khronos Group Inc.
+# Copyright (c) 2015-2016 Valve Corporation
+# Copyright (c) 2015-2016 LunarG, Inc.
+# Copyright (c) 2015-2016 Google 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: Mike Stroyan <stroyan@google.com>
+
+import os,re,sys
+from generator import *
+
+# ThreadGeneratorOptions - subclass of GeneratorOptions.
+#
+# Adds options used by ThreadOutputGenerator objects during threading
+# layer generation.
+#
+# Additional members
+#   prefixText - list of strings to prefix generated header with
+#     (usually a copyright statement + calling convention macros).
+#   protectFile - True if multiple inclusion protection should be
+#     generated (based on the filename) around the entire header.
+#   protectFeature - True if #ifndef..#endif protection should be
+#     generated around a feature interface in the header file.
+#   genFuncPointers - True if function pointer typedefs should be
+#     generated
+#   protectProto - If conditional protection should be generated
+#     around prototype declarations, set to either '#ifdef'
+#     to require opt-in (#ifdef protectProtoStr) or '#ifndef'
+#     to require opt-out (#ifndef protectProtoStr). Otherwise
+#     set to None.
+#   protectProtoStr - #ifdef/#ifndef symbol to use around prototype
+#     declarations, if protectProto is set
+#   apicall - string to use for the function declaration prefix,
+#     such as APICALL on Windows.
+#   apientry - string to use for the calling convention macro,
+#     in typedefs, such as APIENTRY.
+#   apientryp - string to use for the calling convention macro
+#     in function pointer typedefs, such as APIENTRYP.
+#   indentFuncProto - True if prototype declarations should put each
+#     parameter on a separate line
+#   indentFuncPointer - True if typedefed function pointers should put each
+#     parameter on a separate line
+#   alignFuncParam - if nonzero and parameters are being put on a
+#     separate line, align parameter names at the specified column
+class ThreadGeneratorOptions(GeneratorOptions):
+    def __init__(self,
+                 filename = None,
+                 directory = '.',
+                 apiname = None,
+                 profile = None,
+                 versions = '.*',
+                 emitversions = '.*',
+                 defaultExtensions = None,
+                 addExtensions = None,
+                 removeExtensions = None,
+                 sortProcedure = regSortFeatures,
+                 prefixText = "",
+                 genFuncPointers = True,
+                 protectFile = True,
+                 protectFeature = True,
+                 protectProto = None,
+                 protectProtoStr = None,
+                 apicall = '',
+                 apientry = '',
+                 apientryp = '',
+                 indentFuncProto = True,
+                 indentFuncPointer = False,
+                 alignFuncParam = 0):
+        GeneratorOptions.__init__(self, filename, directory, apiname, profile,
+                                  versions, emitversions, defaultExtensions,
+                                  addExtensions, removeExtensions, sortProcedure)
+        self.prefixText      = prefixText
+        self.genFuncPointers = genFuncPointers
+        self.protectFile     = protectFile
+        self.protectFeature  = protectFeature
+        self.protectProto    = protectProto
+        self.protectProtoStr = protectProtoStr
+        self.apicall         = apicall
+        self.apientry        = apientry
+        self.apientryp       = apientryp
+        self.indentFuncProto = indentFuncProto
+        self.indentFuncPointer = indentFuncPointer
+        self.alignFuncParam  = alignFuncParam
+
+# ThreadOutputGenerator - subclass of OutputGenerator.
+# Generates Thread checking framework
+#
+# ---- methods ----
+# ThreadOutputGenerator(errFile, warnFile, diagFile) - args as for
+#   OutputGenerator. Defines additional internal state.
+# ---- methods overriding base class ----
+# beginFile(genOpts)
+# endFile()
+# beginFeature(interface, emit)
+# endFeature()
+# genType(typeinfo,name)
+# genStruct(typeinfo,name)
+# genGroup(groupinfo,name)
+# genEnum(enuminfo, name)
+# genCmd(cmdinfo)
+class ThreadOutputGenerator(OutputGenerator):
+    """Generate specified API interfaces in a specific style, such as a C header"""
+    # This is an ordered list of sections in the header file.
+    TYPE_SECTIONS = ['include', 'define', 'basetype', 'handle', 'enum',
+                     'group', 'bitmask', 'funcpointer', 'struct']
+    ALL_SECTIONS = TYPE_SECTIONS + ['command']
+    def __init__(self,
+                 errFile = sys.stderr,
+                 warnFile = sys.stderr,
+                 diagFile = sys.stdout):
+        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
+        # Internal state - accumulators for different inner block text
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        self.intercepts = []
+
+    # Check if the parameter passed in is a pointer to an array
+    def paramIsArray(self, param):
+        return param.attrib.get('len') is not None
+
+    # Check if the parameter passed in is a pointer
+    def paramIsPointer(self, param):
+        ispointer = False
+        for elem in param:
+            #write('paramIsPointer '+elem.text, file=sys.stderr)
+            #write('elem.tag '+elem.tag, file=sys.stderr)
+            #if (elem.tail is None):
+            #    write('elem.tail is None', file=sys.stderr)
+            #else:
+            #    write('elem.tail '+elem.tail, file=sys.stderr)
+            if ((elem.tag is not 'type') and (elem.tail is not None)) and '*' in elem.tail:
+                ispointer = True
+            #    write('is pointer', file=sys.stderr)
+        return ispointer
+    def makeThreadUseBlock(self, cmd, functionprefix):
+        """Generate C function pointer typedef for <command> Element"""
+        paramdecl = ''
+        thread_check_dispatchable_objects = [
+            "VkCommandBuffer",
+            "VkDevice",
+            "VkInstance",
+            "VkQueue",
+        ]
+        thread_check_nondispatchable_objects = [
+            "VkBuffer",
+            "VkBufferView",
+            "VkCommandPool",
+            "VkDescriptorPool",
+            "VkDescriptorSetLayout",
+            "VkDeviceMemory",
+            "VkEvent",
+            "VkFence",
+            "VkFramebuffer",
+            "VkImage",
+            "VkImageView",
+            "VkPipeline",
+            "VkPipelineCache",
+            "VkPipelineLayout",
+            "VkQueryPool",
+            "VkRenderPass",
+            "VkSampler",
+            "VkSemaphore",
+            "VkShaderModule",
+        ]
+
+        # Find and add any parameters that are thread unsafe
+        params = cmd.findall('param')
+        for param in params:
+            paramname = param.find('name')
+            if False: # self.paramIsPointer(param):
+                paramdecl += '    // not watching use of pointer ' + paramname.text + '\n'
+            else:
+                externsync = param.attrib.get('externsync')
+                if externsync == 'true':
+                    if self.paramIsArray(param):
+                        paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+                        paramdecl += '        ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + '[index]);\n'
+                        paramdecl += '    }\n'
+                    else:
+                        paramdecl += '    ' + functionprefix + 'WriteObject(my_data, ' + paramname.text + ');\n'
+                elif (param.attrib.get('externsync')):
+                    if self.paramIsArray(param):
+                        # Externsync can list pointers to arrays of members to synchronize
+                        paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+                        for member in externsync.split(","):
+                            # Replace first empty [] in member name with index
+                            element = member.replace('[]','[index]',1)
+                            if '[]' in element:
+                                # Replace any second empty [] in element name with
+                                # inner array index based on mapping array names like
+                                # "pSomeThings[]" to "someThingCount" array size.
+                                # This could be more robust by mapping a param member
+                                # name to a struct type and "len" attribute.
+                                limit = element[0:element.find('s[]')] + 'Count'
+                                dotp = limit.rfind('.p')
+                                limit = limit[0:dotp+1] + limit[dotp+2:dotp+3].lower() + limit[dotp+3:]
+                                paramdecl += '        for(uint32_t index2=0;index2<'+limit+';index2++)\n'
+                                element = element.replace('[]','[index2]')
+                            paramdecl += '            ' + functionprefix + 'WriteObject(my_data, ' + element + ');\n'
+                        paramdecl += '    }\n'
+                    else:
+                        # externsync can list members to synchronize
+                        for member in externsync.split(","):
+                            member = str(member).replace("::", "->")
+                            paramdecl += '    ' + functionprefix + 'WriteObject(my_data, ' + member + ');\n'
+                else:
+                    paramtype = param.find('type')
+                    if paramtype is not None:
+                        paramtype = paramtype.text
+                    else:
+                        paramtype = 'None'
+                    if paramtype in thread_check_dispatchable_objects or paramtype in thread_check_nondispatchable_objects:
+                        if self.paramIsArray(param) and ('pPipelines' != paramname.text):
+                            paramdecl += '    for (uint32_t index=0;index<' + param.attrib.get('len') + ';index++) {\n'
+                            paramdecl += '        ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + '[index]);\n'
+                            paramdecl += '    }\n'
+                        elif not self.paramIsPointer(param):
+                            # Pointer params are often being created.
+                            # They are not being read from.
+                            paramdecl += '    ' + functionprefix + 'ReadObject(my_data, ' + paramname.text + ');\n'
+        explicitexternsyncparams = cmd.findall("param[@externsync]")
+        if (explicitexternsyncparams is not None):
+            for param in explicitexternsyncparams:
+                externsyncattrib = param.attrib.get('externsync')
+                paramname = param.find('name')
+                paramdecl += '    // Host access to '
+                if externsyncattrib == 'true':
+                    if self.paramIsArray(param):
+                        paramdecl += 'each member of ' + paramname.text
+                    elif self.paramIsPointer(param):
+                        paramdecl += 'the object referenced by ' + paramname.text
+                    else:
+                        paramdecl += paramname.text
+                else:
+                    paramdecl += externsyncattrib
+                paramdecl += ' must be externally synchronized\n'
+
+        # Find and add any "implicit" parameters that are thread unsafe
+        implicitexternsyncparams = cmd.find('implicitexternsyncparams')
+        if (implicitexternsyncparams is not None):
+            for elem in implicitexternsyncparams:
+                paramdecl += '    // '
+                paramdecl += elem.text
+                paramdecl += ' must be externally synchronized between host accesses\n'
+
+        if (paramdecl == ''):
+            return None
+        else:
+            return paramdecl
+    def beginFile(self, genOpts):
+        OutputGenerator.beginFile(self, genOpts)
+        # C-specific
+        #
+        # Multiple inclusion protection & C++ namespace.
+        if (genOpts.protectFile and self.genOpts.filename):
+            headerSym = '__' + re.sub('\.h', '_h_', os.path.basename(self.genOpts.filename))
+            write('#ifndef', headerSym, file=self.outFile)
+            write('#define', headerSym, '1', file=self.outFile)
+            self.newline()
+        write('namespace threading {', file=self.outFile)
+        self.newline()
+        #
+        # User-supplied prefix text, if any (list of strings)
+        if (genOpts.prefixText):
+            for s in genOpts.prefixText:
+                write(s, file=self.outFile)
+    def endFile(self):
+        # C-specific
+        # Finish C++ namespace and multiple inclusion protection
+        self.newline()
+        # record intercepted procedures
+        write('// intercepts', file=self.outFile)
+        write('struct { const char* name; PFN_vkVoidFunction pFunc;} procmap[] = {', file=self.outFile)
+        write('\n'.join(self.intercepts), file=self.outFile)
+        write('};\n', file=self.outFile)
+        self.newline()
+        write('} // namespace threading', file=self.outFile)
+        if (self.genOpts.protectFile and self.genOpts.filename):
+            self.newline()
+            write('#endif', file=self.outFile)
+        # Finish processing in superclass
+        OutputGenerator.endFile(self)
+    def beginFeature(self, interface, emit):
+        #write('// starting beginFeature', file=self.outFile)
+        # Start processing in superclass
+        OutputGenerator.beginFeature(self, interface, emit)
+        # C-specific
+        # Accumulate includes, defines, types, enums, function pointer typedefs,
+        # end function prototypes separately for this feature. They're only
+        # printed in endFeature().
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        #write('// ending beginFeature', file=self.outFile)
+    def endFeature(self):
+        # C-specific
+        # Actually write the interface to the output file.
+        #write('// starting endFeature', file=self.outFile)
+        if (self.emit):
+            self.newline()
+            if (self.genOpts.protectFeature):
+                write('#ifndef', self.featureName, file=self.outFile)
+            # If type declarations are needed by other features based on
+            # this one, it may be necessary to suppress the ExtraProtect,
+            # or move it below the 'for section...' loop.
+            #write('// endFeature looking at self.featureExtraProtect', file=self.outFile)
+            if (self.featureExtraProtect != None):
+                write('#ifdef', self.featureExtraProtect, file=self.outFile)
+            #write('#define', self.featureName, '1', file=self.outFile)
+            for section in self.TYPE_SECTIONS:
+                #write('// endFeature writing section'+section, file=self.outFile)
+                contents = self.sections[section]
+                if contents:
+                    write('\n'.join(contents), file=self.outFile)
+                    self.newline()
+            #write('// endFeature looking at self.sections[command]', file=self.outFile)
+            if (self.sections['command']):
+                write('\n'.join(self.sections['command']), end='', file=self.outFile)
+                self.newline()
+            if (self.featureExtraProtect != None):
+                write('#endif /*', self.featureExtraProtect, '*/', file=self.outFile)
+            if (self.genOpts.protectFeature):
+                write('#endif /*', self.featureName, '*/', file=self.outFile)
+        # Finish processing in superclass
+        OutputGenerator.endFeature(self)
+        #write('// ending endFeature', file=self.outFile)
+    #
+    # Append a definition to the specified section
+    def appendSection(self, section, text):
+        # self.sections[section].append('SECTION: ' + section + '\n')
+        self.sections[section].append(text)
+    #
+    # Type generation
+    def genType(self, typeinfo, name):
+        pass
+    #
+    # Struct (e.g. C "struct" type) generation.
+    # This is a special case of the <type> tag where the contents are
+    # interpreted as a set of <member> tags instead of freeform C
+    # C type declarations. The <member> tags are just like <param>
+    # tags - they are a declaration of a struct or union member.
+    # Only simple member declarations are supported (no nested
+    # structs etc.)
+    def genStruct(self, typeinfo, typeName):
+        OutputGenerator.genStruct(self, typeinfo, typeName)
+        body = 'typedef ' + typeinfo.elem.get('category') + ' ' + typeName + ' {\n'
+        # paramdecl = self.makeCParamDecl(typeinfo.elem, self.genOpts.alignFuncParam)
+        for member in typeinfo.elem.findall('.//member'):
+            body += self.makeCParamDecl(member, self.genOpts.alignFuncParam)
+            body += ';\n'
+        body += '} ' + typeName + ';\n'
+        self.appendSection('struct', body)
+    #
+    # Group (e.g. C "enum" type) generation.
+    # These are concatenated together with other types.
+    def genGroup(self, groupinfo, groupName):
+        pass
+    # Enumerant generation
+    # <enum> tags may specify their values in several ways, but are usually
+    # just integers.
+    def genEnum(self, enuminfo, name):
+        pass
+    #
+    # Command generation
+    def genCmd(self, cmdinfo, name):
+        # Commands shadowed by interface functions and are not implemented
+        interface_functions = [
+            'vkEnumerateInstanceLayerProperties',
+            'vkEnumerateInstanceExtensionProperties',
+            'vkEnumerateDeviceLayerProperties',
+        ]
+        if name in interface_functions:
+            return
+        special_functions = [
+            'vkGetDeviceProcAddr',
+            'vkGetInstanceProcAddr',
+            'vkCreateDevice',
+            'vkDestroyDevice',
+            'vkCreateInstance',
+            'vkDestroyInstance',
+            'vkAllocateCommandBuffers',
+            'vkFreeCommandBuffers',
+            'vkCreateDebugReportCallbackEXT',
+            'vkDestroyDebugReportCallbackEXT',
+        ]
+        if name in special_functions:
+            decls = self.makeCDecls(cmdinfo.elem)
+            self.appendSection('command', '')
+            self.appendSection('command', '// declare only')
+            self.appendSection('command', decls[0])
+            self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
+            return
+        if "KHR" in name:
+            self.appendSection('command', '// TODO - not wrapping KHR function ' + name)
+            return
+        if ("DebugMarker" in name) and ("EXT" in name):
+            self.appendSection('command', '// TODO - not wrapping EXT function ' + name)
+            return
+        # Determine first if this function needs to be intercepted
+        startthreadsafety = self.makeThreadUseBlock(cmdinfo.elem, 'start')
+        if startthreadsafety is None:
+            return
+        finishthreadsafety = self.makeThreadUseBlock(cmdinfo.elem, 'finish')
+        # record that the function will be intercepted
+        if (self.featureExtraProtect != None):
+            self.intercepts += [ '#ifdef %s' % self.featureExtraProtect ]
+        self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (name,name[2:]) ]
+        if (self.featureExtraProtect != None):
+            self.intercepts += [ '#endif' ]
+
+        OutputGenerator.genCmd(self, cmdinfo, name)
+        #
+        decls = self.makeCDecls(cmdinfo.elem)
+        self.appendSection('command', '')
+        self.appendSection('command', decls[0][:-1])
+        self.appendSection('command', '{')
+        # setup common to call wrappers
+        # first parameter is always dispatchable
+        dispatchable_type = cmdinfo.elem.find('param/type').text
+        dispatchable_name = cmdinfo.elem.find('param/name').text
+        self.appendSection('command', '    dispatch_key key = get_dispatch_key('+dispatchable_name+');')
+        self.appendSection('command', '    layer_data *my_data = get_my_data_ptr(key, layer_data_map);')
+        if dispatchable_type in ["VkPhysicalDevice", "VkInstance"]:
+            self.appendSection('command', '    VkLayerInstanceDispatchTable *pTable = my_data->instance_dispatch_table;')
+        else:
+            self.appendSection('command', '    VkLayerDispatchTable *pTable = my_data->device_dispatch_table;')
+        # Declare result variable, if any.
+        resulttype = cmdinfo.elem.find('proto/type')
+        if (resulttype != None and resulttype.text == 'void'):
+          resulttype = None
+        if (resulttype != None):
+            self.appendSection('command', '    ' + resulttype.text + ' result;')
+            assignresult = 'result = '
+        else:
+            assignresult = ''
+
+        self.appendSection('command', '    bool threadChecks = startMultiThread();')
+        self.appendSection('command', '    if (threadChecks) {')
+        self.appendSection('command', "    "+"\n    ".join(str(startthreadsafety).rstrip().split("\n")))
+        self.appendSection('command', '    }')
+        params = cmdinfo.elem.findall('param/name')
+        paramstext = ','.join([str(param.text) for param in params])
+        API = cmdinfo.elem.attrib.get('name').replace('vk','pTable->',1)
+        self.appendSection('command', '    ' + assignresult + API + '(' + paramstext + ');')
+        self.appendSection('command', '    if (threadChecks) {')
+        self.appendSection('command', "    "+"\n    ".join(str(finishthreadsafety).rstrip().split("\n")))
+        self.appendSection('command', '    } else {')
+        self.appendSection('command', '        finishMultiThread();')
+        self.appendSection('command', '    }')
+        # Return result variable, if any.
+        if (resulttype != None):
+            self.appendSection('command', '    return result;')
+        self.appendSection('command', '}')
+    #
+    # override makeProtoName to drop the "vk" prefix
+    def makeProtoName(self, name, tail):
+        return self.genOpts.apientry + name[2:] + tail
diff --git a/unique_objects_generator.py b/unique_objects_generator.py
new file mode 100644
index 0000000..cdd2808
--- /dev/null
+++ b/unique_objects_generator.py
@@ -0,0 +1,760 @@
+#!/usr/bin/python3 -i
+#
+# Copyright (c) 2015-2016 The Khronos Group Inc.
+# Copyright (c) 2015-2016 Valve Corporation
+# Copyright (c) 2015-2016 LunarG, Inc.
+# Copyright (c) 2015-2016 Google 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: Mark Lobodzinski <mark@lunarg.com>
+
+import os,re,sys
+import xml.etree.ElementTree as etree
+from generator import *
+from collections import namedtuple
+
+# UniqueObjectsGeneratorOptions - subclass of GeneratorOptions.
+#
+# Adds options used by UniqueObjectsOutputGenerator objects during
+# unique objects layer generation.
+#
+# Additional members
+#   prefixText - list of strings to prefix generated header with
+#     (usually a copyright statement + calling convention macros).
+#   protectFile - True if multiple inclusion protection should be
+#     generated (based on the filename) around the entire header.
+#   protectFeature - True if #ifndef..#endif protection should be
+#     generated around a feature interface in the header file.
+#   genFuncPointers - True if function pointer typedefs should be
+#     generated
+#   protectProto - If conditional protection should be generated
+#     around prototype declarations, set to either '#ifdef'
+#     to require opt-in (#ifdef protectProtoStr) or '#ifndef'
+#     to require opt-out (#ifndef protectProtoStr). Otherwise
+#     set to None.
+#   protectProtoStr - #ifdef/#ifndef symbol to use around prototype
+#     declarations, if protectProto is set
+#   apicall - string to use for the function declaration prefix,
+#     such as APICALL on Windows.
+#   apientry - string to use for the calling convention macro,
+#     in typedefs, such as APIENTRY.
+#   apientryp - string to use for the calling convention macro
+#     in function pointer typedefs, such as APIENTRYP.
+#   indentFuncProto - True if prototype declarations should put each
+#     parameter on a separate line
+#   indentFuncPointer - True if typedefed function pointers should put each
+#     parameter on a separate line
+#   alignFuncParam - if nonzero and parameters are being put on a
+#     separate line, align parameter names at the specified column
+class UniqueObjectsGeneratorOptions(GeneratorOptions):
+    def __init__(self,
+                 filename = None,
+                 directory = '.',
+                 apiname = None,
+                 profile = None,
+                 versions = '.*',
+                 emitversions = '.*',
+                 defaultExtensions = None,
+                 addExtensions = None,
+                 removeExtensions = None,
+                 sortProcedure = regSortFeatures,
+                 prefixText = "",
+                 genFuncPointers = True,
+                 protectFile = True,
+                 protectFeature = True,
+                 protectProto = None,
+                 protectProtoStr = None,
+                 apicall = '',
+                 apientry = '',
+                 apientryp = '',
+                 indentFuncProto = True,
+                 indentFuncPointer = False,
+                 alignFuncParam = 0):
+        GeneratorOptions.__init__(self, filename, directory, apiname, profile,
+                                  versions, emitversions, defaultExtensions,
+                                  addExtensions, removeExtensions, sortProcedure)
+        self.prefixText      = prefixText
+        self.genFuncPointers = genFuncPointers
+        self.protectFile     = protectFile
+        self.protectFeature  = protectFeature
+        self.protectProto    = protectProto
+        self.protectProtoStr = protectProtoStr
+        self.apicall         = apicall
+        self.apientry        = apientry
+        self.apientryp       = apientryp
+        self.indentFuncProto = indentFuncProto
+        self.indentFuncPointer = indentFuncPointer
+        self.alignFuncParam  = alignFuncParam
+
+# UniqueObjectsOutputGenerator - subclass of OutputGenerator.
+# Generates unique objects layer non-dispatchable handle-wrapping code.
+#
+# ---- methods ----
+# UniqueObjectsOutputGenerator(errFile, warnFile, diagFile) - args as for OutputGenerator. Defines additional internal state.
+# ---- methods overriding base class ----
+# beginFile(genOpts)
+# endFile()
+# beginFeature(interface, emit)
+# endFeature()
+# genCmd(cmdinfo)
+# genStruct()
+# genType()
+class UniqueObjectsOutputGenerator(OutputGenerator):
+    """Generate UniqueObjects code based on XML element attributes"""
+    # This is an ordered list of sections in the header file.
+    ALL_SECTIONS = ['command']
+    def __init__(self,
+                 errFile = sys.stderr,
+                 warnFile = sys.stderr,
+                 diagFile = sys.stdout):
+        OutputGenerator.__init__(self, errFile, warnFile, diagFile)
+        self.INDENT_SPACES = 4
+        # Commands to ignore
+        self.intercepts = []
+        # Commands which are not autogenerated but still intercepted
+        self.no_autogen_list = [
+            'vkGetDeviceProcAddr', 
+            'vkGetInstanceProcAddr',
+            'vkCreateInstance',
+            'vkDestroyInstance',
+            'vkCreateDevice',
+            'vkDestroyDevice',
+            'vkAllocateMemory',
+            'vkCreateComputePipelines',
+            'vkCreateGraphicsPipelines',
+            'vkCreateSwapchainKHR',
+            'vkGetSwapchainImagesKHR',
+            'vkEnumerateInstanceLayerProperties',
+            'vkEnumerateDeviceLayerProperties',
+            'vkEnumerateInstanceExtensionProperties',
+            ]
+        # Commands shadowed by interface functions and are not implemented
+        self.interface_functions = [
+            'vkGetPhysicalDeviceDisplayPropertiesKHR',
+            'vkGetPhysicalDeviceDisplayPlanePropertiesKHR',
+            'vkGetDisplayPlaneSupportedDisplaysKHR',
+            'vkGetDisplayModePropertiesKHR',
+            # DebugReport APIs are hooked, but handled separately in the source file
+            'vkCreateDebugReportCallbackEXT',
+            'vkDestroyDebugReportCallbackEXT',
+            'vkDebugReportMessageEXT',
+            ]
+        self.headerVersion = None
+        # Internal state - accumulators for different inner block text
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        self.structNames = []                             # List of Vulkan struct typenames
+        self.structTypes = dict()                         # Map of Vulkan struct typename to required VkStructureType
+        self.handleTypes = set()                          # Set of handle type names
+        self.commands = []                                # List of CommandData records for all Vulkan commands
+        self.structMembers = []                           # List of StructMemberData records for all Vulkan structs
+        self.flags = set()                                # Map of flags typenames
+        # Named tuples to store struct and command data
+        self.StructType = namedtuple('StructType', ['name', 'value'])
+        self.CommandParam = namedtuple('CommandParam', ['type', 'name', 'ispointer', 'isconst', 'iscount', 'len', 'extstructs', 'cdecl', 'islocal', 'iscreate', 'isdestroy'])
+        self.CommandData = namedtuple('CommandData', ['name', 'return_type', 'params', 'cdecl'])
+        self.StructMemberData = namedtuple('StructMemberData', ['name', 'members'])
+    #
+    def incIndent(self, indent):
+        inc = ' ' * self.INDENT_SPACES
+        if indent:
+            return indent + inc
+        return inc
+    #
+    def decIndent(self, indent):
+        if indent and (len(indent) > self.INDENT_SPACES):
+            return indent[:-self.INDENT_SPACES]
+        return ''
+    #
+    # Override makeProtoName to drop the "vk" prefix
+    def makeProtoName(self, name, tail):
+        return self.genOpts.apientry + name[2:] + tail
+    #
+    # Check if the parameter passed in is a pointer to an array
+    def paramIsArray(self, param):
+        return param.attrib.get('len') is not None
+    #
+    def beginFile(self, genOpts):
+        OutputGenerator.beginFile(self, genOpts)
+        # User-supplied prefix text, if any (list of strings)
+        if (genOpts.prefixText):
+            for s in genOpts.prefixText:
+                write(s, file=self.outFile)
+        # Namespace
+        self.newline()
+        write('namespace unique_objects {', file = self.outFile)
+    #
+    def endFile(self):
+        self.newline()
+        # Record intercepted procedures
+        write('// intercepts', file=self.outFile)
+        write('struct { const char* name; PFN_vkVoidFunction pFunc;} procmap[] = {', file=self.outFile)
+        write('\n'.join(self.intercepts), file=self.outFile)
+        write('};\n', file=self.outFile)
+        self.newline()
+        write('} // namespace unique_objects', file=self.outFile)
+        # Finish processing in superclass
+        OutputGenerator.endFile(self)
+    #
+    def beginFeature(self, interface, emit):
+        # Start processing in superclass
+        OutputGenerator.beginFeature(self, interface, emit)
+        self.headerVersion = None
+        self.sections = dict([(section, []) for section in self.ALL_SECTIONS])
+        self.structNames = []
+        self.structTypes = dict()
+        self.handleTypes = set()
+        self.commands = []
+        self.structMembers = []
+        self.cmdMembers = []
+        self.flags = set()
+        self.StructMemberData = namedtuple('StructMemberData', ['name', 'members'])
+        self.CmdMemberData = namedtuple('CmdMemberData', ['name', 'members'])
+    #
+    def endFeature(self):
+        # Actually write the interface to the output file.
+        if (self.emit):
+            self.newline()
+            if (self.featureExtraProtect != None):
+                write('#ifdef', self.featureExtraProtect, file=self.outFile)
+            # Write the unique_objects code to the file
+            if (self.sections['command']):
+                if (self.genOpts.protectProto):
+                    write(self.genOpts.protectProto,
+                          self.genOpts.protectProtoStr, file=self.outFile)
+                write('\n'.join(self.sections['command']), end='', file=self.outFile)
+            if (self.featureExtraProtect != None):
+                write('\n#endif //', self.featureExtraProtect, file=self.outFile)
+            else:
+                self.newline()
+        # Finish processing in superclass
+        OutputGenerator.endFeature(self)
+    #
+    def genType(self, typeinfo, name):
+        OutputGenerator.genType(self, typeinfo, name)
+        typeElem = typeinfo.elem
+        # If the type is a struct type, traverse the imbedded <member> tags generating a structure.
+        # Otherwise, emit the tag text.
+        category = typeElem.get('category')
+        if (category == 'struct' or category == 'union'):
+            self.structNames.append(name)
+            self.genStruct(typeinfo, name)
+    #
+    # Append a definition to the specified section
+    def appendSection(self, section, text):
+        # self.sections[section].append('SECTION: ' + section + '\n')
+        self.sections[section].append(text)
+    #
+    # Check if the parameter passed in is a pointer
+    def paramIsPointer(self, param):
+        ispointer = False
+        for elem in param:
+            if ((elem.tag is not 'type') and (elem.tail is not None)) and '*' in elem.tail:
+                ispointer = True
+        return ispointer
+    #
+    # Get the category of a type
+    def getTypeCategory(self, typename):
+        types = self.registry.tree.findall("types/type")
+        for elem in types:
+            if (elem.find("name") is not None and elem.find('name').text == typename) or elem.attrib.get('name') == typename:
+                return elem.attrib.get('category')
+    #
+    # Check if a parent object is dispatchable or not
+    def isHandleTypeNonDispatchable(self, handletype):
+        handle = self.registry.tree.find("types/type/[name='" + handletype + "'][@category='handle']")
+        if handle is not None and handle.find('type').text == 'VK_DEFINE_NON_DISPATCHABLE_HANDLE':
+            return True
+        else:
+            return False
+    #
+    # Retrieve the type and name for a parameter
+    def getTypeNameTuple(self, param):
+        type = ''
+        name = ''
+        for elem in param:
+            if elem.tag == 'type':
+                type = noneStr(elem.text)
+            elif elem.tag == 'name':
+                name = noneStr(elem.text)
+        return (type, name)
+    #
+    # Retrieve the value of the len tag
+    def getLen(self, param):
+        result = None
+        len = param.attrib.get('len')
+        if len and len != 'null-terminated':
+            # For string arrays, 'len' can look like 'count,null-terminated', indicating that we
+            # have a null terminated array of strings.  We strip the null-terminated from the
+            # 'len' field and only return the parameter specifying the string count
+            if 'null-terminated' in len:
+                result = len.split(',')[0]
+            else:
+                result = len
+            # Spec has now notation for len attributes, using :: instead of platform specific pointer symbol
+            result = str(result).replace('::', '->')
+        return result
+    #
+    # Generate a VkStructureType based on a structure typename
+    def genVkStructureType(self, typename):
+        # Add underscore between lowercase then uppercase
+        value = re.sub('([a-z0-9])([A-Z])', r'\1_\2', typename)
+        # Change to uppercase
+        value = value.upper()
+        # Add STRUCTURE_TYPE_
+        return re.sub('VK_', 'VK_STRUCTURE_TYPE_', value)
+    #
+    # Struct parameter check generation.
+    # This is a special case of the <type> tag where the contents are interpreted as a set of
+    # <member> tags instead of freeform C type declarations. The <member> tags are just like
+    # <param> tags - they are a declaration of a struct or union member. Only simple member
+    # declarations are supported (no nested structs etc.)
+    def genStruct(self, typeinfo, typeName):
+        OutputGenerator.genStruct(self, typeinfo, typeName)
+        members = typeinfo.elem.findall('.//member')
+        # Iterate over members once to get length parameters for arrays
+        lens = set()
+        for member in members:
+            len = self.getLen(member)
+            if len:
+                lens.add(len)
+        # Generate member info
+        membersInfo = []
+        for member in members:
+            # Get the member's type and name
+            info = self.getTypeNameTuple(member)
+            type = info[0]
+            name = info[1]
+            cdecl = self.makeCParamDecl(member, 0)
+            # Process VkStructureType
+            if type == 'VkStructureType':
+                # Extract the required struct type value from the comments
+                # embedded in the original text defining the 'typeinfo' element
+                rawXml = etree.tostring(typeinfo.elem).decode('ascii')
+                result = re.search(r'VK_STRUCTURE_TYPE_\w+', rawXml)
+                if result:
+                    value = result.group(0)
+                else:
+                    value = self.genVkStructureType(typeName)
+                # Store the required type value
+                self.structTypes[typeName] = self.StructType(name=name, value=value)
+            # Store pointer/array/string info
+            membersInfo.append(self.CommandParam(type=type,
+                                                 name=name,
+                                                 ispointer=self.paramIsPointer(member),
+                                                 isconst=True if 'const' in cdecl else False,
+                                                 iscount=True if name in lens else False,
+                                                 len=self.getLen(member),
+                                                 extstructs=member.attrib.get('validextensionstructs') if name == 'pNext' else None,
+                                                 cdecl=cdecl,
+                                                 islocal=False,
+                                                 iscreate=False,
+                                                 isdestroy=False))
+        self.structMembers.append(self.StructMemberData(name=typeName, members=membersInfo))
+    #
+    # Insert a lock_guard line
+    def lock_guard(self, indent):
+        return '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % indent
+    #
+    # Determine if a struct has an NDO as a member or an embedded member
+    def struct_contains_ndo(self, struct_item):
+        struct_member_dict = dict(self.structMembers)
+        struct_members = struct_member_dict[struct_item]
+
+        for member in struct_members:
+            if self.isHandleTypeNonDispatchable(member.type):
+                return True
+            elif member.type in struct_member_dict:
+                if self.struct_contains_ndo(member.type) == True:
+                    return True
+        return False
+    #
+    # Return list of struct members which contain, or which sub-structures contain
+    # an NDO in a given list of parameters or members
+    def getParmeterStructsWithNdos(self, item_list):
+        struct_list = set()
+        for item in item_list:
+            paramtype = item.find('type')
+            typecategory = self.getTypeCategory(paramtype.text)
+            if typecategory == 'struct':
+                if self.struct_contains_ndo(paramtype.text) == True:
+                    struct_list.add(item)
+        return struct_list
+    #
+    # Return list of non-dispatchable objects from a given list of parameters or members
+    def getNdosInParameterList(self, item_list, create_func):
+        ndo_list = set()
+        if create_func == True:
+            member_list = item_list[0:-1]
+        else:
+            member_list = item_list
+        for item in member_list:
+            if self.isHandleTypeNonDispatchable(paramtype.text):
+                ndo_list.add(item)
+        return ndo_list
+    #
+    # Generate source for creating a non-dispatchable object
+    def generate_create_ndo_code(self, indent, proto, params, cmd_info):
+        create_ndo_code = ''
+        if True in [create_txt in proto.text for create_txt in ['Create', 'Allocate']]:
+            handle_type = params[-1].find('type')
+            if self.isHandleTypeNonDispatchable(handle_type.text):
+                # Check for special case where multiple handles are returned
+                ndo_array = False
+                if cmd_info[-1].len is not None:
+                    ndo_array = True;
+                handle_name = params[-1].find('name')
+                create_ndo_code += '%sif (VK_SUCCESS == result) {\n' % (indent)
+                indent = self.incIndent(indent)
+                create_ndo_code += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent)
+                ndo_dest = '*%s' % handle_name.text
+                if ndo_array == True:
+                    create_ndo_code += '%sfor (uint32_t index0 = 0; index0 < %s; index0++) {\n' % (indent, cmd_info[-1].len)
+                    indent = self.incIndent(indent)
+                    ndo_dest = '%s[index0]' % cmd_info[-1].name
+                create_ndo_code += '%suint64_t unique_id = global_unique_id++;\n' % (indent)
+                create_ndo_code += '%sdev_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(%s);\n' % (indent, ndo_dest)
+                create_ndo_code += '%s%s = reinterpret_cast<%s&>(unique_id);\n' % (indent, ndo_dest, handle_type.text)
+                if ndo_array == True:
+                    indent = self.decIndent(indent)
+                    create_ndo_code += '%s}\n' % indent
+                indent = self.decIndent(indent)
+                create_ndo_code += '%s}\n' % (indent)
+        return create_ndo_code
+    #
+    # Generate source for destroying a non-dispatchable object
+    def generate_destroy_ndo_code(self, indent, proto, cmd_info):
+        destroy_ndo_code = ''
+        ndo_array = False
+        if True in [destroy_txt in proto.text for destroy_txt in ['Destroy', 'Free']]:
+            # Check for special case where multiple handles are returned
+            if cmd_info[-1].len is not None:
+                ndo_array = True;
+                param = -1
+            else:
+                param = -2
+            if self.isHandleTypeNonDispatchable(cmd_info[param].type) == True:
+                if ndo_array == True:
+                    # This API is freeing an array of handles.  Remove them from the unique_id map.
+                    destroy_ndo_code += '%sif ((VK_SUCCESS == result) && (%s)) {\n' % (indent, cmd_info[param].name)
+                    indent = self.incIndent(indent)
+                    destroy_ndo_code += '%sstd::unique_lock<std::mutex> lock(global_lock);\n' % (indent)
+                    destroy_ndo_code += '%sfor (uint32_t index0 = 0; index0 < %s; index0++) {\n' % (indent, cmd_info[param].len)
+                    indent = self.incIndent(indent)
+                    destroy_ndo_code += '%s%s handle = %s[index0];\n' % (indent, cmd_info[param].type, cmd_info[param].name)
+                    destroy_ndo_code += '%suint64_t unique_id = reinterpret_cast<uint64_t &>(handle);\n' % (indent)
+                    destroy_ndo_code += '%sdev_data->unique_id_mapping.erase(unique_id);\n' % (indent)
+                    indent = self.decIndent(indent);
+                    destroy_ndo_code += '%s}\n' % indent
+                    indent = self.decIndent(indent);
+                    destroy_ndo_code += '%s}\n' % indent
+                else:
+                    # Remove a single handle from the map
+                    destroy_ndo_code += '%sstd::unique_lock<std::mutex> lock(global_lock);\n' % (indent)
+                    destroy_ndo_code += '%suint64_t %s_id = reinterpret_cast<uint64_t &>(%s);\n' % (indent, cmd_info[param].name, cmd_info[param].name)
+                    destroy_ndo_code += '%s%s = (%s)dev_data->unique_id_mapping[%s_id];\n' % (indent, cmd_info[param].name, cmd_info[param].type, cmd_info[param].name)
+                    destroy_ndo_code += '%sdev_data->unique_id_mapping.erase(%s_id);\n' % (indent, cmd_info[param].name)
+                    destroy_ndo_code += '%slock.unlock();\n' % (indent)
+        return ndo_array, destroy_ndo_code
+
+    #
+    # Clean up local declarations
+    def cleanUpLocalDeclarations(self, indent, prefix, name, len):
+        cleanup = '%sif (local_%s%s)\n' % (indent, prefix, name)
+        if len is not None:
+            cleanup += '%s    delete[] local_%s%s;\n' % (indent, prefix, name)
+        else:
+            cleanup += '%s    delete local_%s%s;\n' % (indent, prefix, name)
+        return cleanup
+    #
+    # Output UO code for a single NDO (ndo_count is NULL) or a counted list of NDOs
+    def outputNDOs(self, ndo_type, ndo_name, ndo_count, prefix, index, indent, destroy_func, destroy_array, top_level):
+        decl_code = ''
+        pre_call_code = ''
+        post_call_code = ''
+        if ndo_count is not None:
+            if top_level == True:
+                decl_code += '%s%s *local_%s%s = NULL;\n' % (indent, ndo_type, prefix, ndo_name)
+            pre_call_code += '%s    if (%s%s) {\n' % (indent, prefix, ndo_name)
+            indent = self.incIndent(indent)
+            if top_level == True:
+                pre_call_code += '%s    local_%s%s = new %s[%s];\n' % (indent, prefix, ndo_name, ndo_type, ndo_count)
+                pre_call_code += '%s    for (uint32_t %s = 0; %s < %s; ++%s) {\n' % (indent, index, index, ndo_count, index)
+                indent = self.incIndent(indent)
+                pre_call_code += '%s    local_%s%s[%s] = (%s)dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s[%s])];\n' % (indent, prefix, ndo_name, index, ndo_type, ndo_name, index)
+            else:
+                pre_call_code += '%s    for (uint32_t %s = 0; %s < %s; ++%s) {\n' % (indent, index, index, ndo_count, index)
+                indent = self.incIndent(indent)
+                pre_call_code += '%s    %s%s[%s] = (%s)dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s[%s])];\n' % (indent, prefix, ndo_name, index, ndo_type, prefix, ndo_name, index)
+            indent = self.decIndent(indent)
+            pre_call_code += '%s    }\n' % indent
+            indent = self.decIndent(indent)
+            pre_call_code += '%s    }\n' % indent
+            if top_level == True:
+                post_call_code += '%sif (local_%s%s)\n' % (indent, prefix, ndo_name)
+                indent = self.incIndent(indent)
+                post_call_code += '%sdelete[] local_%s;\n' % (indent, ndo_name)
+        else:
+            if top_level == True:
+                if (destroy_func == False) or (destroy_array == True):       #### LUGMAL This line needs to be skipped for destroy_ndo and not destroy_array
+                    pre_call_code += '%s    %s = (%s)dev_data->unique_id_mapping[reinterpret_cast<uint64_t &>(%s)];\n' % (indent, ndo_name, ndo_type, ndo_name)
+            else:
+                # Make temp copy of this var with the 'local' removed. It may be better to not pass in 'local_'
+                # as part of the string and explicitly print it
+                fix = str(prefix).strip('local_');
+                pre_call_code += '%s    if (%s%s) {\n' % (indent, fix, ndo_name)
+                indent = self.incIndent(indent)
+                pre_call_code += '%s    %s%s = (%s)dev_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, ndo_name, ndo_type, fix, ndo_name)
+                indent = self.decIndent(indent)
+                pre_call_code += '%s    }\n' % indent
+        return decl_code, pre_call_code, post_call_code
+    #
+    # first_level_param indicates if elements are passed directly into the function else they're below a ptr/struct
+    # create_func means that this is API creates or allocates NDOs
+    # destroy_func indicates that this API destroys or frees NDOs
+    # destroy_array means that the destroy_func operated on an array of NDOs
+    def uniquify_members(self, members, indent, prefix, array_index, create_func, destroy_func, destroy_array, first_level_param):
+        decls = ''
+        pre_code = ''
+        post_code = ''
+        struct_member_dict = dict(self.structMembers)
+        index = 'index%s' % str(array_index)
+        array_index += 1
+        # Process any NDOs in this structure and recurse for any sub-structs in this struct
+        for member in members:
+            # Handle NDOs
+            if self.isHandleTypeNonDispatchable(member.type) == True:
+                count_name = member.len  
+                if (count_name is not None):
+                    if first_level_param == False:
+                        count_name = '%s%s' % (prefix, member.len)
+
+                if (first_level_param == False) or (create_func == False):
+                    (tmp_decl, tmp_pre, tmp_post) = self.outputNDOs(member.type, member.name, count_name, prefix, index, indent, destroy_func, destroy_array, first_level_param)
+                    decls += tmp_decl
+                    pre_code += tmp_pre
+                    post_code += tmp_post
+            # Handle Structs that contain NDOs at some level
+            elif member.type in struct_member_dict:
+                # All structs at first level will have an NDO
+                if self.struct_contains_ndo(member.type) == True:
+                    struct_info = struct_member_dict[member.type]
+                    # Struct Array
+                    if member.len is not None:
+                        # Update struct prefix
+                        if first_level_param == True:
+                            new_prefix = 'local_%s' % member.name
+                            # Declare safe_VarType for struct
+                            decls += '%ssafe_%s *%s = NULL;\n' % (indent, member.type, new_prefix)
+                        else:
+                            new_prefix = '%s%s' % (prefix, member.name)
+                        pre_code += '%s    if (%s%s) {\n' % (indent, prefix, member.name)
+                        indent = self.incIndent(indent)
+                        if first_level_param == True:
+                            pre_code += '%s    %s = new safe_%s[%s];\n' % (indent, new_prefix, member.type, member.len)
+                        pre_code += '%s    for (uint32_t %s = 0; %s < %s%s; ++%s) {\n' % (indent, index, index, prefix, member.len, index)
+                        indent = self.incIndent(indent)
+                        if first_level_param == True:
+                            pre_code += '%s    %s[%s].initialize(&%s[%s]);\n' % (indent, new_prefix, index, member.name, index)
+                        local_prefix = '%s[%s].' % (new_prefix, index)
+                        # Process sub-structs in this struct
+                        (tmp_decl, tmp_pre, tmp_post) = self.uniquify_members(struct_info, indent, local_prefix, array_index, create_func, destroy_func, destroy_array, False)
+                        decls += tmp_decl
+                        pre_code += tmp_pre
+                        post_code += tmp_post
+                        indent = self.decIndent(indent)
+                        pre_code += '%s    }\n' % indent
+                        indent = self.decIndent(indent)
+                        pre_code += '%s    }\n' % indent
+                        if first_level_param == True:
+                            post_code += self.cleanUpLocalDeclarations(indent, prefix, member.name, member.len)
+                    # Single Struct
+                    else:
+                        # Update struct prefix
+                        if first_level_param == True:
+                            new_prefix = 'local_%s->' % member.name
+                            decls += '%ssafe_%s *local_%s%s = NULL;\n' % (indent, member.type, prefix, member.name)
+                        else:
+                            new_prefix = '%s%s->' % (prefix, member.name)
+                        # Declare safe_VarType for struct
+                        pre_code += '%s    if (%s%s) {\n' % (indent, prefix, member.name)
+                        indent = self.incIndent(indent)
+                        if first_level_param == True:
+                            pre_code += '%s    local_%s%s = new safe_%s(%s);\n' % (indent, prefix, member.name, member.type, member.name)
+                        # Process sub-structs in this struct
+                        (tmp_decl, tmp_pre, tmp_post) = self.uniquify_members(struct_info, indent, new_prefix, array_index, create_func, destroy_func, destroy_array, False)
+                        decls += tmp_decl
+                        pre_code += tmp_pre
+                        post_code += tmp_post
+                        indent = self.decIndent(indent)
+                        pre_code += '%s    }\n' % indent
+                        if first_level_param == True:
+                            post_code += self.cleanUpLocalDeclarations(indent, prefix, member.name, member.len)
+        return decls, pre_code, post_code
+    #
+    # For a particular API, generate the non-dispatchable-object wrapping/unwrapping code
+    def generate_wrapping_code(self, cmd):
+        indent = '    '
+        proto = cmd.find('proto/name')
+        params = cmd.findall('param')
+        if proto.text is not None:
+            cmd_member_dict = dict(self.cmdMembers)
+            cmd_info = cmd_member_dict[proto.text]
+            # Handle ndo create/allocate operations
+            if cmd_info[0].iscreate:
+                create_ndo_code = self.generate_create_ndo_code(indent, proto, params, cmd_info)
+            else:
+                create_ndo_code = ''
+            # Handle ndo destroy/free operations
+            if cmd_info[0].isdestroy:
+                (destroy_array, destroy_ndo_code) = self.generate_destroy_ndo_code(indent, proto, cmd_info)
+            else:
+                destroy_array = False
+                destroy_ndo_code = ''
+            paramdecl = ''
+            param_pre_code = ''
+            param_post_code = ''
+            create_func = True if create_ndo_code else False
+            destroy_func = True if destroy_ndo_code else False
+            (paramdecl, param_pre_code, param_post_code) = self.uniquify_members(cmd_info, indent, '', 0, create_func, destroy_func, destroy_array, True)
+            param_post_code += create_ndo_code
+            if destroy_ndo_code:
+                if destroy_array == True:
+                    param_post_code += destroy_ndo_code
+                else:
+                    param_pre_code += destroy_ndo_code
+            if param_pre_code:
+                if (not destroy_func) or (destroy_array):
+                    param_pre_code = '%s{\n%s%s%s%s}\n' % ('    ', indent, self.lock_guard(indent), param_pre_code, indent)
+        return paramdecl, param_pre_code, param_post_code
+    #
+    # Capture command parameter info needed to wrap NDOs as well as handling some boilerplate code
+    def genCmd(self, cmdinfo, cmdname):
+        if cmdname in self.interface_functions:
+            return
+        if cmdname in self.no_autogen_list:
+            decls = self.makeCDecls(cmdinfo.elem)
+            self.appendSection('command', '')
+            self.appendSection('command', '// Declare only')
+            self.appendSection('command', decls[0])
+            self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (cmdname,cmdname[2:]) ]
+            return
+        # Add struct-member type information to command parameter information
+        OutputGenerator.genCmd(self, cmdinfo, cmdname)
+        members = cmdinfo.elem.findall('.//param')
+        # Iterate over members once to get length parameters for arrays
+        lens = set()
+        for member in members:
+            len = self.getLen(member)
+            if len:
+                lens.add(len)
+        struct_member_dict = dict(self.structMembers)
+        # Generate member info
+        membersInfo = []
+        for member in members:
+            # Get type and name of member
+            info = self.getTypeNameTuple(member)
+            type = info[0]
+            name = info[1]
+            cdecl = self.makeCParamDecl(member, 0)
+            # Check for parameter name in lens set
+            iscount = True if name in lens else False
+            len = self.getLen(member)
+            isconst = True if 'const' in cdecl else False
+            ispointer = self.paramIsPointer(member)
+            # Mark param as local if it is an array of NDOs
+            islocal = False;
+            if self.isHandleTypeNonDispatchable(type) == True:
+                if (len is not None) and (isconst == True):
+                    islocal = True
+            # Or if it's a struct that contains an NDO
+            elif type in struct_member_dict:
+                if self.struct_contains_ndo(type) == True:
+                    islocal = True
+
+            isdestroy = True if True in [destroy_txt in cmdname for destroy_txt in ['Destroy', 'Free']] else False
+            iscreate = True if True in [create_txt in cmdname for create_txt in ['Create', 'Allocate']] else False
+
+            membersInfo.append(self.CommandParam(type=type,
+                                                 name=name,
+                                                 ispointer=ispointer,
+                                                 isconst=isconst,
+                                                 iscount=iscount,
+                                                 len=len,
+                                                 extstructs=member.attrib.get('validextensionstructs') if name == 'pNext' else None,
+                                                 cdecl=cdecl,
+                                                 islocal=islocal,
+                                                 iscreate=iscreate,
+                                                 isdestroy=isdestroy))
+        self.cmdMembers.append(self.CmdMemberData(name=cmdname, members=membersInfo))
+        # Generate NDO wrapping/unwrapping code for all parameters
+        (api_decls, api_pre, api_post) = self.generate_wrapping_code(cmdinfo.elem)
+        # If API doesn't contain an NDO's, don't fool with it
+        if not api_decls and not api_pre and not api_post:
+            return
+        # Record that the function will be intercepted
+        if (self.featureExtraProtect != None):
+            self.intercepts += [ '#ifdef %s' % self.featureExtraProtect ]
+        self.intercepts += [ '    {"%s", reinterpret_cast<PFN_vkVoidFunction>(%s)},' % (cmdname,cmdname[2:]) ]
+        if (self.featureExtraProtect != None):
+            self.intercepts += [ '#endif' ]
+        decls = self.makeCDecls(cmdinfo.elem)
+        self.appendSection('command', '')
+        self.appendSection('command', decls[0][:-1])
+        self.appendSection('command', '{')
+        # Setup common to call wrappers, first parameter is always dispatchable
+        dispatchable_type = cmdinfo.elem.find('param/type').text
+        dispatchable_name = cmdinfo.elem.find('param/name').text
+        # Generate local instance/pdev/device data lookup
+        self.appendSection('command', '    layer_data *dev_data = get_my_data_ptr(get_dispatch_key('+dispatchable_name+'), layer_data_map);')
+        # Handle return values, if any
+        resulttype = cmdinfo.elem.find('proto/type')
+        if (resulttype != None and resulttype.text == 'void'):
+          resulttype = None
+        if (resulttype != None):
+            assignresult = resulttype.text + ' result = '
+        else:
+            assignresult = ''
+        # Pre-pend declarations and pre-api-call codegen
+        if api_decls:
+            self.appendSection('command', "\n".join(str(api_decls).rstrip().split("\n")))
+        if api_pre:
+            self.appendSection('command', "\n".join(str(api_pre).rstrip().split("\n")))
+        # Generate the API call itself
+        # Gather the parameter items
+        params = cmdinfo.elem.findall('param/name')
+        # Pull out the text for each of the parameters, separate them by commas in a list
+        paramstext = ', '.join([str(param.text) for param in params])
+        # If any of these paramters has been replaced by a local var, fix up the list
+        cmd_member_dict = dict(self.cmdMembers)
+        params = cmd_member_dict[cmdname]
+        for param in params:
+            if param.islocal == True:
+                if param.ispointer == True:
+                    paramstext = paramstext.replace(param.name, '(%s %s*)local_%s' % ('const', param.type, param.name))
+                else:
+                    paramstext = paramstext.replace(param.name, '(%s %s)local_%s' % ('const', param.type, param.name))
+        # Use correct dispatch table
+        if dispatchable_type in ["VkPhysicalDevice", "VkInstance"]:
+            API = cmdinfo.elem.attrib.get('name').replace('vk','dev_data->instance_dispatch_table->',1)
+        else:
+            API = cmdinfo.elem.attrib.get('name').replace('vk','dev_data->device_dispatch_table->',1)
+        # Put all this together for the final down-chain call
+        self.appendSection('command', '    ' + assignresult + API + '(' + paramstext + ');')
+        # And add the post-API-call codegen
+        self.appendSection('command', "\n".join(str(api_post).rstrip().split("\n")))
+        # Handle the return result variable, if any
+        if (resulttype != None):
+            self.appendSection('command', '    return result;')
+        self.appendSection('command', '}')
diff --git a/update_external_sources.bat b/update_external_sources.bat
index 4775af7..65d151f 100644
--- a/update_external_sources.bat
+++ b/update_external_sources.bat
@@ -13,7 +13,7 @@
 setlocal EnableDelayedExpansion
 set errorCode=0
 set BUILD_DIR=%~dp0
-set BASE_DIR=%BUILD_DIR%external
+set BASE_DIR="%BUILD_DIR%external"
 set GLSLANG_DIR=%BASE_DIR%\glslang
 set SPIRV_TOOLS_DIR=%BASE_DIR%\spirv-tools
 
diff --git a/update_external_sources.sh b/update_external_sources.sh
index ea294f6..6f87903 100755
--- a/update_external_sources.sh
+++ b/update_external_sources.sh
@@ -3,74 +3,74 @@
 
 set -e
 
-GLSLANG_REVISION=$(cat $PWD/glslang_revision)
-SPIRV_TOOLS_REVISION=$(cat $PWD/spirv-tools_revision)
-SPIRV_HEADERS_REVISION=$(cat $PWD/spirv-headers_revision)
-echo "GLSLANG_REVISION=$GLSLANG_REVISION"
-echo "SPIRV_TOOLS_REVISION=$SPIRV_TOOLS_REVISION"
-echo "SPIRV_HEADERS_REVISION=$SPIRV_HEADERS_REVISION"
+GLSLANG_REVISION=$(cat "${PWD}"/glslang_revision)
+SPIRV_TOOLS_REVISION=$(cat "${PWD}"/spirv-tools_revision)
+SPIRV_HEADERS_REVISION=$(cat "${PWD}"/spirv-headers_revision)
+echo "GLSLANG_REVISION=${GLSLANG_REVISION}"
+echo "SPIRV_TOOLS_REVISION=${SPIRV_TOOLS_REVISION}"
+echo "SPIRV_HEADERS_REVISION=${SPIRV_HEADERS_REVISION}"
 
 BUILDDIR=$PWD
 BASEDIR=$BUILDDIR/external
 
 function create_glslang () {
-   rm -rf $BASEDIR/glslang
-   echo "Creating local glslang repository ($BASEDIR/glslang)."
-   mkdir -p $BASEDIR/glslang
-   cd $BASEDIR/glslang
+   rm -rf "${BASEDIR}"/glslang
+   echo "Creating local glslang repository (${BASEDIR}/glslang)."
+   mkdir -p "${BASEDIR}"/glslang
+   cd "${BASEDIR}"/glslang
    git clone https://github.com/KhronosGroup/glslang.git .
-   git checkout $GLSLANG_REVISION
+   git checkout ${GLSLANG_REVISION}
 }
 
 function update_glslang () {
-   echo "Updating $BASEDIR/glslang"
-   cd $BASEDIR/glslang
+   echo "Updating ${BASEDIR}/glslang"
+   cd "${BASEDIR}"/glslang
    git fetch --all
-   git checkout --force $GLSLANG_REVISION
+   git checkout --force ${GLSLANG_REVISION}
 }
 
 function create_spirv-tools () {
-   rm -rf $BASEDIR/spirv-tools
-   echo "Creating local spirv-tools repository ($BASEDIR/spirv-tools)."
-   mkdir -p $BASEDIR/spirv-tools
-   cd $BASEDIR/spirv-tools
+   rm -rf "${BASEDIR}"/spirv-tools
+   echo "Creating local spirv-tools repository (${BASEDIR}/spirv-tools)."
+   mkdir -p "${BASEDIR}"/spirv-tools
+   cd "${BASEDIR}"/spirv-tools
    git clone https://github.com/KhronosGroup/SPIRV-Tools.git .
-   git checkout $SPIRV_TOOLS_REVISION
-   mkdir -p $BASEDIR/spirv-tools/external/spirv-headers
-   cd $BASEDIR/spirv-tools/external/spirv-headers
+   git checkout ${SPIRV_TOOLS_REVISION}
+   mkdir -p "${BASEDIR}"/spirv-tools/external/spirv-headers
+   cd "${BASEDIR}"/spirv-tools/external/spirv-headers
    git clone https://github.com/KhronosGroup/SPIRV-Headers .
-   git checkout $SPIRV_HEADERS_REVISION
+   git checkout ${SPIRV_HEADERS_REVISION}
 }
 
 function update_spirv-tools () {
-   echo "Updating $BASEDIR/spirv-tools"
-   cd $BASEDIR/spirv-tools
+   echo "Updating ${BASEDIR}/spirv-tools"
+   cd "${BASEDIR}"/spirv-tools
    git fetch --all
-   git checkout $SPIRV_TOOLS_REVISION
-   if [ ! -d "$BASEDIR/spirv-tools/external/spirv-headers" -o ! -d "$BASEDIR/spirv-tools/external/spirv-headers/.git" ]; then
-      mkdir -p $BASEDIR/spirv-tools/external/spirv-headers
-      cd $BASEDIR/spirv-tools/external/spirv-headers
+   git checkout ${SPIRV_TOOLS_REVISION}
+   if [ ! -d "${BASEDIR}/spirv-tools/external/spirv-headers" -o ! -d "${BASEDIR}/spirv-tools/external/spirv-headers/.git" ]; then
+      mkdir -p "${BASEDIR}"/spirv-tools/external/spirv-headers
+      cd "${BASEDIR}"/spirv-tools/external/spirv-headers
       git clone https://github.com/KhronosGroup/SPIRV-Headers .
    else
-      cd $BASEDIR/spirv-tools/external/spirv-headers
+      cd "${BASEDIR}"/spirv-tools/external/spirv-headers
       git fetch --all
    fi
-   git checkout $SPIRV_HEADERS_REVISION
+   git checkout ${SPIRV_HEADERS_REVISION}
 }
 
 function build_glslang () {
-   echo "Building $BASEDIR/glslang"
-   cd $BASEDIR/glslang
+   echo "Building ${BASEDIR}/glslang"
+   cd "${BASEDIR}"/glslang
    mkdir -p build
    cd build
    cmake -D CMAKE_BUILD_TYPE=Release ..
-   make
+   make -j $(nproc)
    make install
 }
 
 function build_spirv-tools () {
-   echo "Building $BASEDIR/spirv-tools"
-   cd $BASEDIR/spirv-tools
+   echo "Building ${BASEDIR}/spirv-tools"
+   cd "${BASEDIR}"/spirv-tools
    mkdir -p build
    cd build
    cmake -D CMAKE_BUILD_TYPE=Release ..
@@ -115,8 +115,8 @@
   done
 fi
 
-if [ $INCLUDE_GLSLANG == "true" ]; then
-  if [ ! -d "$BASEDIR/glslang" -o ! -d "$BASEDIR/glslang/.git" -o -d "$BASEDIR/glslang/.svn" ]; then
+if [ ${INCLUDE_GLSLANG} == "true" ]; then
+  if [ ! -d "${BASEDIR}/glslang" -o ! -d "${BASEDIR}/glslang/.git" -o -d "${BASEDIR}/glslang/.svn" ]; then
      create_glslang
   fi
   update_glslang
@@ -124,8 +124,8 @@
 fi
 
 
-if [ $INCLUDE_SPIRV_TOOLS == "true" ]; then
-    if [ ! -d "$BASEDIR/spirv-tools" -o ! -d "$BASEDIR/spirv-tools/.git" ]; then
+if [ ${INCLUDE_SPIRV_TOOLS} == "true" ]; then
+    if [ ! -d "${BASEDIR}/spirv-tools" -o ! -d "${BASEDIR}/spirv-tools/.git" ]; then
        create_spirv-tools
     fi
     update_spirv-tools
diff --git a/vk-generate.py b/vk-generate.py
index e8fcead..2b173ff 100755
--- a/vk-generate.py
+++ b/vk-generate.py
@@ -155,68 +155,39 @@
             stmts.append("    // Core instance function pointers")
             stmts.append("    table->GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) gpa(instance, \"vkGetInstanceProcAddr\");")
 
-            KHR_printed = False
-            EXT_printed = False
-            Win32_printed = False
-            XLIB_printed = False
-            XCB_printed = False
-            MIR_printed = False
-            WAY_printed = False
-            Android_printed = False
             for proto in self.protos:
                 if proto.params[0].ty != "VkInstance" and proto.params[0].ty != "VkPhysicalDevice" or \
                   proto.name == "CreateDevice" or proto.name == "GetInstanceProcAddr":
                     continue
-                if Win32_printed and 'Win32' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
-                    Win32_printed = False
-                if XLIB_printed and 'Xlib' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
-                    XLIB_printed = False
-                if XCB_printed and 'Xcb' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
-                    XCB_printed = False
-                if MIR_printed and 'Mir' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
-                    MIR_printed = False
-                if WAY_printed and 'Wayland' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
-                    WAY_printed = False
-                if Android_printed and 'Android' not in proto.name:
-                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
-                    Android_printed = False
+                # Protect platform-dependent APIs with #ifdef
                 if 'KHR' in proto.name and 'Win32' in proto.name:
-                    if not Win32_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
-                        Win32_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_WIN32_KHR")
                 if 'KHR' in proto.name and 'Xlib' in proto.name:
-                    if not XLIB_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
-                        XLIB_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_XLIB_KHR")
                 if 'KHR' in proto.name and 'Xcb' in proto.name:
-                    if not XCB_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
-                        XCB_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_XCB_KHR")
                 if 'KHR' in proto.name and 'Mir' in proto.name:
-                    if not MIR_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
-                        MIR_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_MIR_KHR")
                 if 'KHR' in proto.name and 'Wayland' in proto.name:
-                    if not WAY_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
-                        WAY_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_WAYLAND_KHR")
                 if 'KHR' in proto.name and 'Android' in proto.name:
-                    if not Android_printed:
-                        stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
-                        Android_printed = True
-                if 'KHR' in proto.name and not KHR_printed:
-                    stmts.append("    // KHR instance extension function pointers")
-                    KHR_printed = True
-                if 'EXT' in proto.name and not EXT_printed:
-                    stmts.append("    // EXT instance extension function pointers")
-                    EXT_printed = True
+                    stmts.append("#ifdef VK_USE_PLATFORM_ANDROID_KHR")
+                # Output dispatch table entry
                 stmts.append("    table->%s = (PFN_vk%s) gpa(instance, \"vk%s\");" %
                       (proto.name, proto.name, proto.name))
+                # If entry was protected by an #ifdef, close with a #endif
+                if 'KHR' in proto.name and 'Win32' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WIN32_KHR")
+                if 'KHR' in proto.name and 'Xlib' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XLIB_KHR")
+                if 'KHR' in proto.name and 'Xcb' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_XCB_KHR")
+                if 'KHR' in proto.name and 'Mir' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_MIR_KHR")
+                if 'KHR' in proto.name and 'Wayland' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_WAYLAND_KHR")
+                if 'KHR' in proto.name and 'Android' in proto.name:
+                    stmts.append("#endif // VK_USE_PLATFORM_ANDROID_KHR")
             func.append("static inline void %s_init_instance_dispatch_table(" % self.prefix)
             func.append("%s        VkInstance instance," % (" " * len(self.prefix)))
             func.append("%s        VkLayerInstanceDispatchTable *table," % (" " * len(self.prefix)))
diff --git a/vk-layer-generate.py b/vk-layer-generate.py
deleted file mode 100755
index 015826f..0000000
--- a/vk-layer-generate.py
+++ /dev/null
@@ -1,1085 +0,0 @@
-#!/usr/bin/env python3
-#
-# VK
-#
-# Copyright (c) 2015-2016 The Khronos Group Inc.
-# Copyright (c) 2015-2016 Valve Corporation
-# Copyright (c) 2015-2016 LunarG, Inc.
-# Copyright (c) 2015-2016 Google 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: Courtney Goeltzenleuchter <courtneygo@google.com>
-# Author: Jon Ashburn <jon@lunarg.com>
-# Author: Mark Lobodzinski <mark@lunarg.com>
-# Author: Mike Stroyan <stroyan@google.com>
-# Author: Tony Barbour <tony@LunarG.com>
-# Author: Chia-I Wu <olv@google.com>
-# Author: Gwan-gyeong Mun <kk.moon@samsung.com>
-
-import sys
-import os
-import re
-
-import vulkan
-import vk_helper
-from source_line_info import sourcelineinfo
-from collections import defaultdict
-
-def proto_is_global(proto):
-    global_function_names = [
-        "CreateInstance",
-        "EnumerateInstanceLayerProperties",
-        "EnumerateInstanceExtensionProperties",
-        "EnumerateDeviceLayerProperties",
-        "EnumerateDeviceExtensionProperties",
-        "CreateXcbSurfaceKHR",
-        "GetPhysicalDeviceXcbPresentationSupportKHR",
-        "CreateXlibSurfaceKHR",
-        "GetPhysicalDeviceXlibPresentationSupportKHR",
-        "CreateWaylandSurfaceKHR",
-        "GetPhysicalDeviceWaylandPresentationSupportKHR",
-        "CreateMirSurfaceKHR",
-        "GetPhysicalDeviceMirPresentationSupportKHR",
-        "CreateAndroidSurfaceKHR",
-        "CreateWin32SurfaceKHR",
-        "GetPhysicalDeviceWin32PresentationSupportKHR",
-        "GetPhysicalDeviceDisplayPropertiesKHR",
-        "GetPhysicalDeviceDisplayPlanePropertiesKHR",
-        "GetDisplayPlaneSupportedDisplaysKHR",
-        "GetDisplayModePropertiesKHR",
-        "CreateDisplayModeKHR",
-        "GetDisplayPlaneCapabilitiesKHR",
-        "CreateDisplayPlaneSurfaceKHR"
-    ]
-    if proto.params[0].ty == "VkInstance" or proto.params[0].ty == "VkPhysicalDevice" or proto.name in global_function_names:
-       return True
-    else:
-       return False
-
-def wsi_name(ext_name):
-    wsi_prefix = ""
-    if 'Xcb' in ext_name:
-        wsi_prefix = 'XCB'
-    elif 'Xlib' in ext_name:
-        wsi_prefix = 'XLIB'
-    elif 'Win32' in ext_name:
-        wsi_prefix = 'WIN32'
-    elif 'Mir' in ext_name:
-        wsi_prefix = 'MIR'
-    elif 'Wayland' in ext_name:
-        wsi_prefix = 'WAYLAND'
-    elif 'Android' in ext_name:
-        wsi_prefix = 'ANDROID'
-    else:
-        wsi_prefix = ''
-    return wsi_prefix
-
-def wsi_ifdef(ext_name):
-    wsi_prefix = wsi_name(ext_name)
-    if not wsi_prefix:
-        return ''
-    else:
-        return "#ifdef VK_USE_PLATFORM_%s_KHR" % wsi_prefix
-
-def wsi_endif(ext_name):
-    wsi_prefix = wsi_name(ext_name)
-    if not wsi_prefix:
-        return ''
-    else:
-        return "#endif  // VK_USE_PLATFORM_%s_KHR" % wsi_prefix
-
-def generate_get_proc_addr_check(name):
-    return "    if (!%s || %s[0] != 'v' || %s[1] != 'k')\n" \
-           "        return NULL;" % ((name,) * 3)
-
-def ucc_to_U_C_C(CamelCase):
-    temp = re.sub('(.)([A-Z][a-z]+)',  r'\1_\2', CamelCase)
-    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).upper()
-
-# Parse complete struct chain and add any new ndo_uses to the dict
-def gather_object_uses_in_struct(obj_list, struct_type):
-    struct_uses = {}
-    if vk_helper.typedef_rev_dict[struct_type] in vk_helper.struct_dict:
-        struct_type = vk_helper.typedef_rev_dict[struct_type]
-        # Parse elements of this struct param to identify objects and/or arrays of objects
-        for m in sorted(vk_helper.struct_dict[struct_type]):
-            array_len = "%s" % (str(vk_helper.struct_dict[struct_type][m]['array_size']))
-            base_type = vk_helper.struct_dict[struct_type][m]['type']
-            mem_name = vk_helper.struct_dict[struct_type][m]['name']
-            if array_len != '0':
-                mem_name = "%s[%s]" % (mem_name, array_len)
-            if base_type in obj_list:
-                #if array_len not in ndo_uses:
-                #    struct_uses[array_len] = []
-                #struct_uses[array_len].append("%s%s,%s" % (name_prefix, struct_name, base_type))
-                struct_uses[mem_name] = base_type
-            elif vk_helper.is_type(base_type, 'struct'):
-                sub_uses = gather_object_uses_in_struct(obj_list, base_type)
-                if len(sub_uses) > 0:
-                    struct_uses[mem_name] = sub_uses
-    return struct_uses
-
-# For the given list of object types, Parse the given list of params
-#  and return dict of params that use one of the obj_list types
-# Format of the dict is that terminal elements have <name>,<type>
-#  non-terminal elements will have <name>[<array_size>]
-# TODO : This analysis could be done up-front at vk_helper time
-def get_object_uses(obj_list, params):
-    obj_uses = {}
-    local_decls = {}
-    param_count = 'NONE' # track params that give array sizes
-    for p in params:
-        base_type = p.ty.replace('const ', '').strip('*')
-        array_len = ''
-        is_ptr = False
-        if 'count' in p.name.lower():
-            param_count = p.name
-        ptr_txt = ''
-        if '*' in p.ty:
-            is_ptr = True
-            ptr_txt = '*'
-        if base_type in obj_list:
-            if is_ptr and 'const' in p.ty and param_count != 'NONE':
-                array_len = "[%s]" % param_count
-                # Non-arrays we can overwrite in place, but need local decl for arrays
-                local_decls[p.name] = '%s%s' % (base_type, ptr_txt)
-            #if array_len not in obj_uses:
-            #    obj_uses[array_len] = {}
-            # obj_uses[array_len][p.name] = base_type
-            obj_uses["%s%s" % (p.name, array_len)] = base_type
-        elif vk_helper.is_type(base_type, 'struct'):
-            struct_name = p.name
-            if 'NONE' != param_count:
-                struct_name = "%s[%s]" % (struct_name, param_count)
-            struct_uses = gather_object_uses_in_struct(obj_list, base_type)
-            if len(struct_uses) > 0:
-                obj_uses[struct_name] = struct_uses
-                # This is a top-level struct w/ uses below it, so need local decl
-                local_decls['%s' % (p.name)] = '%s%s' % (base_type, ptr_txt)
-    return (obj_uses, local_decls)
-
-class Subcommand(object):
-    def __init__(self, outfile):
-        self.outfile = outfile
-        self.headers = vulkan.headers
-        self.protos = vulkan.protos
-        self.no_addr = False
-        self.layer_name = ""
-        self.lineinfo = sourcelineinfo()
-        self.wsi = sys.argv[1]
-
-    def run(self):
-        if self.outfile:
-            with open(self.outfile, "w") as outfile:
-                outfile.write(self.generate())
-        else:
-            print(self.generate())
-
-    def generate(self):
-        copyright = self.generate_copyright()
-        header = self.generate_header()
-        body = self.generate_body()
-        footer = self.generate_footer()
-
-        contents = []
-        if copyright:
-            contents.append(copyright)
-        if header:
-            contents.append(header)
-        if body:
-            contents.append(body)
-        if footer:
-            contents.append(footer)
-
-        return "\n\n".join(contents)
-
-    def generate_copyright(self):
-        return """/* THIS FILE IS GENERATED.  DO NOT EDIT. */
-
-/*
- * Copyright (c) 2015-2016 The Khronos Group Inc.
- * Copyright (c) 2015-2016 Valve Corporation
- * Copyright (c) 2015-2016 LunarG, Inc.
- * Copyright (c) 2015-2016 Google, 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: Courtney Goeltzenleuchter <courtneygo@google.com>
- * Author: Jon Ashburn <jon@lunarg.com>
- * Author: Mark Lobodzinski <mark@lunarg.com>
- * Author: Mike Stroyan <stroyan@google.com>
- * Author: Tony Barbour <tony@LunarG.com>
- */"""
-
-    def generate_header(self):
-        return "\n".join(["#include <" + h + ">" for h in self.headers])
-
-    def generate_body(self):
-        pass
-
-    def generate_footer(self):
-        pass
-
-    # Return set of printf '%' qualifier and input to that qualifier
-    def _get_printf_params(self, vk_type, name, output_param, cpp=False):
-        # TODO : Need ENUM and STRUCT checks here
-        if vk_helper.is_type(vk_type, 'enum'):#"_TYPE" in vk_type: # TODO : This should be generic ENUM check
-            return ("%s", "string_%s(%s)" % (vk_type.replace('const ', '').strip('*'), name))
-        if "char*" == vk_type:
-            return ("%s", name)
-        if "uint64" in vk_type:
-            if '*' in vk_type:
-                return ("%lu", "*%s" % name)
-            return ("%lu", name)
-        if vk_type.strip('*') in vulkan.object_non_dispatch_list:
-            if '*' in vk_type:
-                return ("%lu", "%s" % name)
-            return ("%lu", "%s" % name)
-        if "size" in vk_type:
-            if '*' in vk_type:
-                return ("%lu", "(unsigned long)*%s" % name)
-            return ("%lu", "(unsigned long)%s" % name)
-        if "float" in vk_type:
-            if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
-                if cpp:
-                    return ("[%i, %i, %i, %i]", '"[" << %s[0] << "," << %s[1] << "," << %s[2] << "," << %s[3] << "]"' % (name, name, name, name))
-                return ("[%f, %f, %f, %f]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
-            return ("%f", name)
-        if "bool" in vk_type.lower() or 'xcb_randr_crtc_t' in vk_type:
-            return ("%u", name)
-        if True in [t in vk_type.lower() for t in ["int", "flags", "mask", "xcb_window_t"]]:
-            if '[' in vk_type: # handle array, current hard-coded to 4 (TODO: Make this dynamic)
-                if cpp:
-                    return ("[%i, %i, %i, %i]", "%s[0] << %s[1] << %s[2] << %s[3]" % (name, name, name, name))
-                return ("[%i, %i, %i, %i]", "%s[0], %s[1], %s[2], %s[3]" % (name, name, name, name))
-            if '*' in vk_type:
-                if 'pUserData' == name:
-                    return ("%i", "((pUserData == 0) ? 0 : *(pUserData))")
-                if 'const' in vk_type.lower():
-                    return ("0x%p", "(void*)(%s)" % name)
-                return ("%i", "*(%s)" % name)
-            return ("%i", name)
-        # TODO : This is special-cased as there's only one "format" param currently and it's nice to expand it
-        if "VkFormat" == vk_type:
-            if cpp:
-                return ("0x%p", "&%s" % name)
-            return ("{%s.channelFormat = %%s, %s.numericFormat = %%s}" % (name, name), "string_VK_COLOR_COMPONENT_FORMAT(%s.channelFormat), string_VK_FORMAT_RANGE_SIZE(%s.numericFormat)" % (name, name))
-        if output_param:
-            return ("0x%p", "(void*)*%s" % name)
-        if vk_helper.is_type(vk_type, 'struct') and '*' not in vk_type:
-            return ("0x%p", "(void*)(&%s)" % name)
-        return ("0x%p", "(void*)(%s)" % name)
-
-    def _gen_create_msg_callback(self):
-        r_body = []
-        r_body.append('%s' % self.lineinfo.get())
-        r_body.append('VKAPI_ATTR VkResult VKAPI_CALL CreateDebugReportCallbackEXT(')
-        r_body.append('        VkInstance                                   instance,')
-        r_body.append('        const VkDebugReportCallbackCreateInfoEXT*    pCreateInfo,')
-        r_body.append('        const VkAllocationCallbacks*                 pAllocator,')
-        r_body.append('        VkDebugReportCallbackEXT*                    pCallback)')
-        r_body.append('{')
-        # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['unique_objects']:
-            r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
-            r_body.append('    VkResult result = pInstanceTable->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
-            r_body.append('    if (VK_SUCCESS == result) {')
-            r_body.append('        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
-            r_body.append('        result = layer_create_msg_callback(my_data->report_data,')
-            r_body.append('                                           false,')
-            r_body.append('                                           pCreateInfo,')
-            r_body.append('                                           pAllocator,')
-            r_body.append('                                           pCallback);')
-            r_body.append('    }')
-            r_body.append('    return result;')
-        else:
-            r_body.append('    VkResult result = instance_dispatch_table(instance)->CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pCallback);')
-            r_body.append('    if (VK_SUCCESS == result) {')
-            r_body.append('        layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
-            r_body.append('        result = layer_create_msg_callback(my_data->report_data, false, pCreateInfo, pAllocator, pCallback);')
-            r_body.append('    }')
-            r_body.append('    return result;')
-        r_body.append('}')
-        return "\n".join(r_body)
-
-    def _gen_destroy_msg_callback(self):
-        r_body = []
-        r_body.append('%s' % self.lineinfo.get())
-        r_body.append('VKAPI_ATTR void VKAPI_CALL DestroyDebugReportCallbackEXT(VkInstance instance, VkDebugReportCallbackEXT msgCallback, const VkAllocationCallbacks *pAllocator)')
-        r_body.append('{')
-        # Switch to this code section for the new per-instance storage and debug callbacks
-        if self.layer_name in ['unique_objects']:
-            r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = get_dispatch_table(%s_instance_table_map, instance);' % self.layer_name )
-        else:
-            r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
-        r_body.append('    pInstanceTable->DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);')
-        r_body.append('    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);')
-        r_body.append('    layer_destroy_msg_callback(my_data->report_data, msgCallback, pAllocator);')
-        r_body.append('}')
-        return "\n".join(r_body)
-
-    def _gen_debug_report_msg(self):
-        r_body = []
-        r_body.append('%s' % self.lineinfo.get())
-        r_body.append('VKAPI_ATTR void VKAPI_CALL DebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT    flags, VkDebugReportObjectTypeEXT objType, uint64_t object, size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg)')
-        r_body.append('{')
-        # Switch to this code section for the new per-instance storage and debug callbacks
-        r_body.append('    VkLayerInstanceDispatchTable *pInstanceTable = instance_dispatch_table(instance);')
-        r_body.append('    pInstanceTable->DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);')
-        r_body.append('}')
-        return "\n".join(r_body)
-
-    def _gen_layer_logging_workaround(self):
-        body = []
-        body.append('%s' % self.lineinfo.get())
-        body.append('// vk_layer_logging.h expects these to be defined')
-        body.append('')
-        body.append('VKAPI_ATTR VkResult VKAPI_CALL')
-        body.append('vkCreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT *pCreateInfo,')
-        body.append('                               const VkAllocationCallbacks *pAllocator, VkDebugReportCallbackEXT *pMsgCallback) {')
-        body.append('    return %s::CreateDebugReportCallbackEXT(instance, pCreateInfo, pAllocator, pMsgCallback);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VKAPI_ATTR void VKAPI_CALL vkDestroyDebugReportCallbackEXT(VkInstance instance,')
-        body.append('                                                                           VkDebugReportCallbackEXT msgCallback,')
-        body.append('                                                                           const VkAllocationCallbacks *pAllocator) {')
-        body.append('    %s::DestroyDebugReportCallbackEXT(instance, msgCallback, pAllocator);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VKAPI_ATTR void VKAPI_CALL')
-        body.append('vkDebugReportMessageEXT(VkInstance instance, VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objType, uint64_t object,')
-        body.append('                        size_t location, int32_t msgCode, const char *pLayerPrefix, const char *pMsg) {')
-        body.append('    %s::DebugReportMessageEXT(instance, flags, objType, object, location, msgCode, pLayerPrefix, pMsg);' % self.layer_name)
-        body.append('}')
-
-        return "\n".join(body)
-
-    def _gen_layer_interface_v0_functions(self):
-        body = []
-        body.append('%s' % self.lineinfo.get())
-        body.append('// loader-layer interface v0, just wrappers since there is only a layer')
-        body.append('')
-
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,  VkExtensionProperties* pProperties)')
-        body.append('{')
-        body.append('    return %s::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceLayerProperties(uint32_t *pCount,  VkLayerProperties* pProperties)')
-        body.append('{')
-        body.append('    return %s::EnumerateInstanceLayerProperties(pCount, pProperties);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)')
-        body.append('{')
-        body.append('    // the layer command handles VK_NULL_HANDLE just fine internally')
-        body.append('    assert(physicalDevice == VK_NULL_HANDLE);')
-        body.append('    return %s::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char *funcName)')
-        body.append('{')
-        body.append('    return %s::GetDeviceProcAddr(dev, funcName);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetInstanceProcAddr(VkInstance instance, const char *funcName)')
-        body.append('{')
-        body.append('    return %s::GetInstanceProcAddr(instance, funcName);' % self.layer_name)
-        body.append('}')
-        body.append('')
-        body.append('VK_LAYER_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,')
-        body.append('                                                                                    const char *pLayerName, uint32_t *pCount,')
-        body.append('                                                                                    VkExtensionProperties *pProperties)')
-        body.append('{')
-        body.append('    // the layer command handles VK_NULL_HANDLE just fine internally')
-        body.append('    assert(physicalDevice == VK_NULL_HANDLE);')
-        body.append('    return %s::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);' % self.layer_name)
-        body.append('}')
-
-        return "\n".join(body)
-
-    def _generate_dispatch_entrypoints(self, qual=""):
-        if qual:
-            qual += " "
-
-        funcs = []
-        intercepted = []
-        for proto in self.protos:
-            if proto.name in ["EnumerateInstanceExtensionProperties",
-                              "EnumerateInstanceLayerProperties",
-                              "EnumerateDeviceLayerProperties",
-                              "GetDeviceProcAddr",
-                              "GetInstanceProcAddr"]:
-                funcs.append(proto.c_func(attr="VKAPI") + ';')
-                intercepted.append(proto)
-            else:
-                intercept = self.generate_intercept(proto, qual)
-                if intercept is None:
-                    # fill in default intercept for certain entrypoints
-                    if 'CreateDebugReportCallbackEXT' == proto.name:
-                        intercept = self._gen_layer_dbg_create_msg_callback()
-                    elif 'DestroyDebugReportCallbackEXT' == proto.name:
-                        intercept = self._gen_layer_dbg_destroy_msg_callback()
-                    elif 'DebugReportMessageEXT' == proto.name:
-                        intercept = self._gen_debug_report_msg()
-                    elif 'CreateDevice' == proto.name:
-                        funcs.append('/* CreateDevice HERE */')
-
-                if intercept is not None:
-                    funcs.append(intercept)
-                    if not "KHR" in proto.name:
-                        intercepted.append(proto)
-
-        instance_lookups = []
-        device_lookups = []
-        for proto in intercepted:
-            if proto_is_global(proto):
-                instance_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
-                instance_lookups.append("    return (PFN_vkVoidFunction) %s;" % (proto.name))
-            else:
-                device_lookups.append("if (!strcmp(name, \"%s\"))" % proto.name)
-                device_lookups.append("    return (PFN_vkVoidFunction) %s;" % (proto.name))
-
-        # add customized intercept_core_device_command
-        body = []
-        body.append('%s' % self.lineinfo.get())
-        body.append("static inline PFN_vkVoidFunction intercept_core_device_command(const char *name)")
-        body.append("{")
-        body.append(generate_get_proc_addr_check("name"))
-        body.append("")
-        body.append("    name += 2;")
-        body.append("    %s" % "\n    ".join(device_lookups))
-        body.append("")
-        body.append("    return NULL;")
-        body.append("}")
-        # add intercept_core_instance_command
-        body.append("static inline PFN_vkVoidFunction intercept_core_instance_command(const char *name)")
-        body.append("{")
-        body.append(generate_get_proc_addr_check("name"))
-        body.append("")
-        body.append("    name += 2;")
-        body.append("    %s" % "\n    ".join(instance_lookups))
-        body.append("")
-        body.append("    return NULL;")
-        body.append("}")
-
-        funcs.append("\n".join(body))
-        return "\n\n".join(funcs)
-
-    def _generate_extensions(self):
-        exts = []
-        exts.append('%s' % self.lineinfo.get())
-        exts.append(self._gen_create_msg_callback())
-        exts.append(self._gen_destroy_msg_callback())
-        exts.append(self._gen_debug_report_msg())
-        return "\n".join(exts)
-
-    def _generate_layer_introspection_function(self):
-        body = []
-        body.append('%s' % self.lineinfo.get())
-        body.append('static const VkLayerProperties globalLayerProps = {')
-        body.append('    "VK_LAYER_GOOGLE_%s",' % self.layer_name)
-        body.append('    VK_LAYER_API_VERSION, // specVersion')
-        body.append('    1, // implementationVersion')
-        body.append('    "Google Validation Layer"')
-        body.append('};')
-        body.append('')
-
-        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t *pCount,  VkLayerProperties* pProperties)')
-        body.append('{')
-        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
-        body.append('}')
-        body.append('')
-        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice, uint32_t *pCount, VkLayerProperties* pProperties)')
-        body.append('{')
-        body.append('    return util_GetLayerProperties(1, &globalLayerProps, pCount, pProperties);')
-        body.append('}')
-        body.append('')
-        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(const char *pLayerName, uint32_t *pCount,  VkExtensionProperties* pProperties)')
-        body.append('{')
-        body.append('    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))')
-        body.append('        return util_GetExtensionProperties(0, NULL, pCount, pProperties);')
-        body.append('')
-        body.append('    return VK_ERROR_LAYER_NOT_PRESENT;')
-        body.append('}')
-        body.append('')
-        body.append('VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,')
-        body.append('                                                                  const char *pLayerName, uint32_t *pCount,')
-        body.append('                                                                  VkExtensionProperties *pProperties)')
-        body.append('{')
-        body.append('    if (pLayerName && !strcmp(pLayerName, globalLayerProps.layerName))')
-        body.append('        return util_GetExtensionProperties(0, nullptr, pCount, pProperties);')
-        body.append('')
-        body.append('    assert(physicalDevice);')
-        body.append('    VkLayerInstanceDispatchTable* pTable = get_dispatch_table(%s_instance_table_map, physicalDevice);' % self.layer_name)
-        body.append('    return pTable->EnumerateDeviceExtensionProperties(physicalDevice, NULL, pCount, pProperties);')
-        body.append('}')
-
-        return "\n".join(body)
-
-    def _generate_layer_gpa_function(self, extensions=[], instance_extensions=[]):
-        func_body = []
-#
-# New style of GPA Functions for the new layer_data/layer_logging changes
-#
-        if self.layer_name in ['unique_objects']:
-            for ext_enable, ext_list in extensions:
-                func_body.append('%s' % self.lineinfo.get())
-                func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkDevice dev)' % ext_enable)
-                func_body.append('{')
-                func_body.append('    if (dev) {')
-                func_body.append('        layer_data *my_data = get_my_data_ptr(get_dispatch_key(dev), layer_data_map);')
-                func_body.append('        if (!my_data->%s)' % ext_enable)
-                func_body.append('            return nullptr;')
-                func_body.append('    }\n')
-
-                for ext_name in ext_list:
-                    func_body.append('    if (!strcmp("%s", name))\n'
-                                     '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:]))
-                func_body.append('\n    return nullptr;')
-                func_body.append('}\n')
-
-            func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)\n"
-                             "{\n"
-                             "    PFN_vkVoidFunction addr;\n"
-                             "    addr = intercept_core_device_command(funcName);\n"
-                             "    if (addr)\n"
-                             "        return addr;\n"
-                             "    assert(device);\n")
-            for ext_enable, _ in extensions:
-                func_body.append('    addr = intercept_%s_command(funcName, device);' % ext_enable)
-                func_body.append('    if (addr)\n'
-                                 '        return addr;')
-            func_body.append("\n    if (get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr == NULL)\n"
-                             "        return NULL;\n"
-                             "    return get_dispatch_table(%s_device_table_map, device)->GetDeviceProcAddr(device, funcName);\n"
-                             "}\n" % (self.layer_name, self.layer_name))
-
-            # The WSI-related extensions have independent extension enables
-            wsi_sub_enables = {'WIN32': 'win32_enabled',
-                               'XLIB': 'xlib_enabled',
-                               'XCB': 'xcb_enabled',
-                               'MIR': 'mir_enabled',
-                               'WAYLAND': 'wayland_enabled',
-                               'ANDROID': 'android_enabled'}
-
-            for ext_enable, ext_list in instance_extensions:
-                func_body.append('%s' % self.lineinfo.get())
-                func_body.append('static inline PFN_vkVoidFunction intercept_%s_command(const char *name, VkInstance instance)' % ext_enable)
-                func_body.append('{')
-                if ext_enable == 'msg_callback_get_proc_addr':
-                    func_body.append("    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n"
-                                     "    return debug_report_get_instance_proc_addr(my_data->report_data, name);")
-                else:
-                    func_body.append("    VkLayerInstanceDispatchTable* pTable = get_dispatch_table(%s_instance_table_map, instance);" % self.layer_name)
-                    func_body.append('    if (instanceExtMap.size() == 0 || !instanceExtMap[pTable].%s)' % ext_enable)
-                    func_body.append('        return nullptr;\n')
-
-                    for ext_name in ext_list:
-                        if wsi_name(ext_name):
-                            func_body.append('%s' % wsi_ifdef(ext_name))
-                            if wsi_sub_enables[wsi_name(ext_name)]:
-                                func_body.append('    if ((instanceExtMap[pTable].%s == true) && !strcmp("%s", name))\n'
-                                                 '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (wsi_sub_enables[wsi_name(ext_name)], ext_name, ext_name[2:]))
-                        else:
-                            func_body.append('    if (!strcmp("%s", name))\n'
-                                             '        return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (ext_name, ext_name[2:]))
-                        if wsi_name(ext_name):
-                            func_body.append('%s' % wsi_endif(ext_name))
-
-                    func_body.append('\n    return nullptr;')
-                func_body.append('}\n')
-
-            func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
-                             "{\n"
-                             "    PFN_vkVoidFunction addr;\n"
-                             "    addr = intercept_core_instance_command(funcName);\n"
-                             "    if (!addr) {\n"
-                             "        addr = intercept_core_device_command(funcName);\n"
-                             "    }")
-
-            for ext_enable, _ in extensions:
-                func_body.append("    if (!addr) {\n"
-                                 "        addr = intercept_%s_command(funcName, VkDevice(VK_NULL_HANDLE));\n"
-                                 "    }" % ext_enable)
-
-            func_body.append("    if (addr) {\n"
-                             "        return addr;\n"
-                             "    }\n"
-                             "    assert(instance);\n"
-                             )
-
-            for ext_enable, _ in instance_extensions:
-                func_body.append('    addr = intercept_%s_command(funcName, instance);' % ext_enable)
-                func_body.append('    if (addr)\n'
-                                 '        return addr;\n')
-
-            func_body.append("    if (get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr == NULL) {\n"
-                             "        return NULL;\n"
-                             "    }\n"
-                             "    return get_dispatch_table(%s_instance_table_map, instance)->GetInstanceProcAddr(instance, funcName);\n"
-                             "}\n" % (self.layer_name, self.layer_name))
-            return "\n".join(func_body)
-        else:
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)\n"
-                             "{\n"
-                             "    PFN_vkVoidFunction addr;\n")
-            func_body.append("\n"
-                             "    loader_platform_thread_once(&initOnce, init%s);\n\n"
-                             "    addr = intercept_core_device_command(funcName);\n"
-                             "    if (addr)\n"
-                             "        return addr;" % self.layer_name)
-            func_body.append("    assert(device);\n")
-            func_body.append('')
-            func_body.append('    VkLayerDispatchTable *pDisp =  device_dispatch_table(device);')
-            if 0 != len(extensions):
-                extra_space = ""
-                for (ext_enable, ext_list) in extensions:
-                    if 0 != len(ext_enable):
-                        func_body.append('    if (deviceExtMap.size() != 0 && deviceExtMap[pDisp].%s)' % ext_enable)
-                        func_body.append('    {')
-                        extra_space = "    "
-                    for ext_name in ext_list:
-                        func_body.append('    %sif (!strcmp("%s", funcName))\n'
-                                         '            return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name))
-                    if 0 != len(ext_enable):
-                        func_body.append('    }')
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append("    {\n"
-                             "        if (pDisp->GetDeviceProcAddr == NULL)\n"
-                             "            return NULL;\n"
-                             "        return pDisp->GetDeviceProcAddr(device, funcName);\n"
-                             "    }\n"
-                             "}\n")
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append("VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)\n"
-                             "{\n"
-                             "    PFN_vkVoidFunction addr;\n"
-                             )
-            func_body.append(
-                             "    loader_platform_thread_once(&initOnce, init%s);\n\n"
-                             "    addr = intercept_core_instance_command(funcName);\n"
-                             "    if (addr)\n"
-                             "        return addr;" % self.layer_name)
-            func_body.append("    assert(instance);\n")
-            func_body.append("")
-            func_body.append("    VkLayerInstanceDispatchTable* pTable = instance_dispatch_table(instance);\n")
-            if 0 != len(instance_extensions):
-                extra_space = ""
-                for (ext_enable, ext_list) in instance_extensions:
-                    if 0 != len(ext_enable):
-                        if ext_enable == 'msg_callback_get_proc_addr':
-                            func_body.append("    layer_data *my_data = get_my_data_ptr(get_dispatch_key(instance), layer_data_map);\n"
-                                     "    addr = debug_report_get_instance_proc_addr(my_data->report_data, funcName);\n"
-                                     "    if (addr) {\n"
-                                     "        return addr;\n"
-                                     "    }\n")
-                        else:
-                            func_body.append('    if (instanceExtMap.size() != 0 && instanceExtMap[pTable].%s)' % ext_enable)
-                            func_body.append('    {')
-                            extra_space = "    "
-                            for ext_name in ext_list:
-                                if wsi_name(ext_name):
-                                    func_body.append('%s' % wsi_ifdef(ext_name))
-                                func_body.append('    %sif (!strcmp("%s", funcName))\n'
-                                         '            return reinterpret_cast<PFN_vkVoidFunction>(%s);' % (extra_space, ext_name, ext_name))
-                                if wsi_name(ext_name):
-                                    func_body.append('%s' % wsi_endif(ext_name))
-                            if 0 != len(ext_enable):
-                                func_body.append('    }\n')
-
-            func_body.append("    if (pTable->GetInstanceProcAddr == NULL)\n"
-                             "        return NULL;\n"
-                             "    return pTable->GetInstanceProcAddr(instance, funcName);\n"
-                             "}\n")
-            return "\n".join(func_body)
-
-
-    def _generate_layer_initialization(self, init_opts=False, prefix='vk', lockname=None, condname=None):
-        func_body = ["#include \"vk_dispatch_table_helper.h\""]
-        func_body.append('%s' % self.lineinfo.get())
-        func_body.append('static void init_%s(layer_data *my_data, const VkAllocationCallbacks *pAllocator)\n'
-                         '{\n' % self.layer_name)
-        if init_opts:
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append('')
-            func_body.append('    layer_debug_actions(my_data->report_data, my_data->logging_callback, pAllocator, "lunarg_%s");' % self.layer_name)
-            func_body.append('')
-        if lockname is not None:
-            func_body.append('%s' % self.lineinfo.get())
-            func_body.append("    if (!%sLockInitialized)" % lockname)
-            func_body.append("    {")
-            func_body.append("        // TODO/TBD: Need to delete this mutex sometime.  How???")
-            func_body.append("        loader_platform_thread_create_mutex(&%sLock);" % lockname)
-            if condname is not None:
-                func_body.append("        loader_platform_thread_init_cond(&%sCond);" % condname)
-            func_body.append("        %sLockInitialized = 1;" % lockname)
-            func_body.append("    }")
-        func_body.append("}\n")
-        func_body.append('')
-        return "\n".join(func_body)
-
-class UniqueObjectsSubcommand(Subcommand):
-    def generate_header(self):
-        header_txt = []
-        header_txt.append('%s' % self.lineinfo.get())
-        header_txt.append('#include "unique_objects.h"')
-        return "\n".join(header_txt)
-
-    # Generate UniqueObjects code for given struct_uses dict of objects that need to be unwrapped
-    # vector_name_set is used to make sure we don't replicate vector names
-    # first_level_param indicates if elements are passed directly into the function else they're below a ptr/struct
-    # TODO : Comment this code
-    def _gen_obj_code(self, struct_uses, param_type, indent, prefix, array_index, vector_name_set, first_level_param):
-        decls = ''
-        pre_code = ''
-        post_code = ''
-        for obj in sorted(struct_uses):
-            name = obj
-            array = ''
-            if '[' in obj:
-                (name, array) = obj.split('[')
-                array = array.strip(']')
-            ptr_type = False
-            if 'p' == obj[0] and obj[1] != obj[1].lower(): # TODO : Not ideal way to determine ptr
-                ptr_type = True
-            if isinstance(struct_uses[obj], dict):
-                local_prefix = ''
-                name = '%s%s' % (prefix, name)
-                if ptr_type:
-                    if first_level_param and name in param_type:
-                        pre_code += '%sif (%s) {\n' % (indent, name)
-                    else: # shadow ptr will have been initialized at this point so check it vs. source ptr
-                        pre_code += '%sif (local_%s) {\n' % (indent, name)
-                    indent += '    '
-                if array != '':
-                    if 'p' == array[0] and array[1] != array[1].lower(): # TODO : Not ideal way to determine ptr
-                        count_prefix = '*'
-                    else:
-                        count_prefix = ''
-                    idx = 'idx%s' % str(array_index)
-                    array_index += 1
-                    if first_level_param and name in param_type:
-                        pre_code += '%slocal_%s = new safe_%s[%s%s];\n' % (indent, name, param_type[name].strip('*'), count_prefix, array)
-                        post_code += '    if (local_%s)\n' % (name)
-                        post_code += '        delete[] local_%s;\n' % (name)
-                    pre_code += '%sfor (uint32_t %s=0; %s<%s%s%s; ++%s) {\n' % (indent, idx, idx, count_prefix, prefix, array, idx)
-                    indent += '    '
-                    if first_level_param:
-                        pre_code += '%slocal_%s[%s].initialize(&%s[%s]);\n' % (indent, name, idx, name, idx)
-                    local_prefix = '%s[%s].' % (name, idx)
-                elif ptr_type:
-                    if first_level_param and name in param_type:
-                        pre_code += '%slocal_%s = new safe_%s(%s);\n' % (indent, name, param_type[name].strip('*'), name)
-                        post_code += '    if (local_%s)\n' % (name)
-                        post_code += '        delete local_%s;\n' % (name)
-                    local_prefix = '%s->' % (name)
-                else:
-                    local_prefix = '%s.' % (name)
-                assert isinstance(decls, object)
-                (tmp_decl, tmp_pre, tmp_post) = self._gen_obj_code(struct_uses[obj], param_type, indent, local_prefix, array_index, vector_name_set, False)
-                decls += tmp_decl
-                pre_code += tmp_pre
-                post_code += tmp_post
-                if array != '':
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-                if ptr_type:
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-            else:
-                if (array_index > 0) or array != '': # TODO : This is not ideal, really want to know if we're anywhere under an array
-                    if first_level_param:
-                        decls += '%s%s* local_%s = NULL;\n' % (indent, struct_uses[obj], name)
-                    if array != '' and not first_level_param: # ptrs under structs will have been initialized so use local_*
-                        pre_code += '%sif (local_%s%s) {\n' %(indent, prefix, name)
-                    else:
-                        pre_code += '%sif (%s%s) {\n' %(indent, prefix, name)
-                    indent += '    '
-                    if array != '':
-                        idx = 'idx%s' % str(array_index)
-                        array_index += 1
-                        if first_level_param:
-                            pre_code += '%slocal_%s = new %s[%s];\n' % (indent, name, struct_uses[obj], array)
-                            post_code += '    if (local_%s)\n' % (name)
-                            post_code += '        delete[] local_%s;\n' % (name)
-                        pre_code += '%sfor (uint32_t %s=0; %s<%s%s; ++%s) {\n' % (indent, idx, idx, prefix, array, idx)
-                        indent += '    '
-                        name = '%s[%s]' % (name, idx)
-                    if name not in vector_name_set:
-                        vector_name_set.add(name)
-                    pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name)
-                    if array != '':
-                        indent = indent[4:]
-                        pre_code += '%s}\n' % (indent)
-                    indent = indent[4:]
-                    pre_code += '%s}\n' % (indent)
-                else:
-                    pre_code += '%s\n' % (self.lineinfo.get())
-                    if '->' in prefix: # need to update local struct
-                        pre_code += '%slocal_%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<const uint64_t &>(%s%s)];\n' % (indent, prefix, name, struct_uses[obj], prefix, name)
-                    else:
-                        pre_code += '%s%s = (%s)my_map_data->unique_id_mapping[reinterpret_cast<uint64_t &>(%s)];\n' % (indent, name, struct_uses[obj], name)
-        return decls, pre_code, post_code
-
-    def generate_intercept(self, proto, qual):
-        create_func = False
-        destroy_func = False
-        last_param_index = None #typcially we look at all params for ndos
-        pre_call_txt = '' # code prior to calling down chain such as unwrap uses of ndos
-        post_call_txt = '' # code following call down chain such to wrap newly created ndos, or destroy local wrap struct
-        funcs = []
-        indent = '    ' # indent level for generated code
-        decl = proto.c_func(attr="VKAPI")
-        # A few API cases that are manual code
-        # TODO : Special case Create*Pipelines funcs to handle creating multiple unique objects
-        explicit_unique_objects_functions = ['GetSwapchainImagesKHR',
-                                             'CreateSwapchainKHR',
-                                             'CreateInstance',
-                                             'DestroyInstance',
-                                             'CreateDevice',
-                                             'DestroyDevice',
-                                             'AllocateMemory',
-                                             'CreateComputePipelines',
-                                             'CreateGraphicsPipelines',
-                                             'GetPhysicalDeviceDisplayPropertiesKHR',
-                                             'GetDisplayPlaneSupportedDisplaysKHR',
-                                             'GetDisplayModePropertiesKHR'
-                                             ]
-        # TODO : This is hacky, need to make this a more general-purpose solution for all layers
-        ifdef_dict = {'CreateXcbSurfaceKHR': 'VK_USE_PLATFORM_XCB_KHR',
-                      'CreateAndroidSurfaceKHR': 'VK_USE_PLATFORM_ANDROID_KHR',
-                      'CreateWin32SurfaceKHR': 'VK_USE_PLATFORM_WIN32_KHR',
-                      'CreateXlibSurfaceKHR': 'VK_USE_PLATFORM_XLIB_KHR',
-                      'CreateWaylandSurfaceKHR': 'VK_USE_PLATFORM_WAYLAND_KHR',
-                      'CreateMirSurfaceKHR': 'VK_USE_PLATFORM_MIR_KHR'}
-        # Give special treatment to create functions that return multiple new objects
-        # This dict stores array name and size of array
-        custom_create_dict = {'pDescriptorSets' : 'pAllocateInfo->descriptorSetCount'}
-        pre_call_txt += '%s\n' % (self.lineinfo.get())
-        if proto.name in explicit_unique_objects_functions:
-            funcs.append('%s%s\n'
-                     '{\n'
-                     '    return explicit_%s;\n'
-                     '}' % (qual, decl, proto.c_call()))
-            return "".join(funcs)
-        if True in [create_txt in proto.name for create_txt in ['Create', 'Allocate']]:
-            create_func = True
-            last_param_index = -1 # For create funcs don't care if last param is ndo
-        if True in [destroy_txt in proto.name for destroy_txt in ['Destroy', 'Free']]:
-            destroy_obj_type = proto.params[-2].ty
-            if destroy_obj_type in vulkan.object_non_dispatch_list:
-                destroy_func = True
-
-        # First thing we need to do is gather uses of non-dispatchable-objects (ndos)
-        (struct_uses, local_decls) = get_object_uses(vulkan.object_non_dispatch_list, proto.params[1:last_param_index])
-
-        dispatch_param = proto.params[0].name
-        if 'CreateInstance' in proto.name:
-           dispatch_param = '*' + proto.params[1].name
-        pre_call_txt += '%slayer_data *my_map_data = get_my_data_ptr(get_dispatch_key(%s), layer_data_map);\n' % (indent, dispatch_param)
-        if len(struct_uses) > 0:
-            pre_call_txt += '// STRUCT USES:%s\n' % sorted(struct_uses)
-            if len(local_decls) > 0:
-                pre_call_txt += '//LOCAL DECLS:%s\n' % sorted(local_decls)
-            if destroy_func: # only one object
-                pre_call_txt += '%sstd::unique_lock<std::mutex> lock(global_lock);\n' % (indent)
-                for del_obj in sorted(struct_uses):
-                    pre_call_txt += '%suint64_t local_%s = reinterpret_cast<uint64_t &>(%s);\n' % (indent, del_obj, del_obj)
-                    pre_call_txt += '%s%s = (%s)my_map_data->unique_id_mapping[local_%s];\n' % (indent, del_obj, struct_uses[del_obj], del_obj)
-                pre_call_txt += '%smy_map_data->unique_id_mapping.erase(local_%s);\n' % (indent, proto.params[-2].name)
-                pre_call_txt += '%slock.unlock();\n' % (indent)
-                (pre_decl, pre_code, post_code) = ('', '', '')
-            else:
-                (pre_decl, pre_code, post_code) = self._gen_obj_code(struct_uses, local_decls, '    ', '', 0, set(), True)
-            # This is a bit hacky but works for now. Need to decl local versions of top-level structs
-            for ld in sorted(local_decls):
-                init_null_txt = 'NULL';
-                if '*' not in local_decls[ld]:
-                    init_null_txt = '{}';
-                if local_decls[ld].strip('*') not in vulkan.object_non_dispatch_list:
-                    pre_decl += '    safe_%s local_%s = %s;\n' % (local_decls[ld], ld, init_null_txt)
-            if pre_code != '': # lock around map uses
-                pre_code = '%s{\n%sstd::lock_guard<std::mutex> lock(global_lock);\n%s%s}\n' % (indent, indent, pre_code, indent)
-            pre_call_txt += '%s%s' % (pre_decl, pre_code)
-            post_call_txt += '%s' % (post_code)
-        elif create_func:
-            base_type = proto.params[-1].ty.replace('const ', '').strip('*')
-            if base_type not in vulkan.object_non_dispatch_list:
-                return None
-        else:
-            return None
-
-        ret_val = ''
-        ret_stmt = ''
-        if proto.ret != "void":
-            ret_val = "%s result = " % proto.ret
-            ret_stmt = "    return result;\n"
-        if create_func:
-            obj_type = proto.params[-1].ty.strip('*')
-            obj_name = proto.params[-1].name
-            if obj_type in vulkan.object_non_dispatch_list:
-                local_name = "unique%s" % obj_type[2:]
-                post_call_txt += '%sif (VK_SUCCESS == result) {\n' % (indent)
-                indent += '    '
-                post_call_txt += '%sstd::lock_guard<std::mutex> lock(global_lock);\n' % (indent)
-                if obj_name in custom_create_dict:
-                    post_call_txt += '%s\n' % (self.lineinfo.get())
-                    local_name = '%ss' % (local_name) # add 's' to end for vector of many
-                    post_call_txt += '%sfor (uint32_t i=0; i<%s; ++i) {\n' % (indent, custom_create_dict[obj_name])
-                    indent += '    '
-                    post_call_txt += '%suint64_t unique_id = global_unique_id++;\n' % (indent)
-                    post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(%s[i]);\n' % (indent, obj_name)
-                    post_call_txt += '%s%s[i] = reinterpret_cast<%s&>(unique_id);\n' % (indent, obj_name, obj_type)
-                    indent = indent[4:]
-                    post_call_txt += '%s}\n' % (indent)
-                else:
-                    post_call_txt += '%s\n' % (self.lineinfo.get())
-                    post_call_txt += '%suint64_t unique_id = global_unique_id++;\n' % (indent)
-                    post_call_txt += '%smy_map_data->unique_id_mapping[unique_id] = reinterpret_cast<uint64_t &>(*%s);\n' % (indent, obj_name)
-                    post_call_txt += '%s*%s = reinterpret_cast<%s&>(unique_id);\n' % (indent, obj_name, obj_type)
-                indent = indent[4:]
-                post_call_txt += '%s}\n' % (indent)
-
-        call_sig = proto.c_call()
-        # Replace default params with any custom local params
-        for ld in local_decls:
-            const_qualifier = ''
-            for p in proto.params:
-                if ld == p.name and 'const' in p.ty:
-                    const_qualifier = 'const'
-            call_sig = call_sig.replace(ld, '(%s %s)local_%s' % (const_qualifier, local_decls[ld], ld))
-        if proto_is_global(proto):
-            table_type = "instance"
-        else:
-            table_type = "device"
-        pre_call_txt += '%s\n' % (self.lineinfo.get())
-        open_ifdef = ''
-        close_ifdef = ''
-        if proto.name in ifdef_dict:
-            open_ifdef = '#ifdef %s\n' % (ifdef_dict[proto.name])
-            close_ifdef = '#endif\n'
-        funcs.append('%s'
-                     '%s%s\n'
-                     '{\n'
-                     '%s'
-                     '    %sget_dispatch_table(unique_objects_%s_table_map, %s)->%s;\n'
-                     '%s'
-                     '%s'
-                     '}\n'
-                     '%s' % (open_ifdef, qual, decl, pre_call_txt, ret_val, table_type, dispatch_param, call_sig, post_call_txt, ret_stmt, close_ifdef))
-        return "\n\n".join(funcs)
-
-    def generate_body(self):
-        self.layer_name = "unique_objects"
-        extensions=[('wsi_enabled',
-                     ['vkCreateSwapchainKHR',
-                      'vkDestroySwapchainKHR', 'vkGetSwapchainImagesKHR',
-                      'vkAcquireNextImageKHR', 'vkQueuePresentKHR'])]
-        surface_wsi_instance_exts = [
-                      'vkDestroySurfaceKHR',
-                      'vkGetPhysicalDeviceSurfaceSupportKHR',
-                      'vkGetPhysicalDeviceSurfaceCapabilitiesKHR',
-                      'vkGetPhysicalDeviceSurfaceFormatsKHR',
-                      'vkGetPhysicalDeviceSurfacePresentModesKHR']
-        display_wsi_instance_exts = [
-                      'vkGetPhysicalDeviceDisplayPropertiesKHR',
-                      'vkGetPhysicalDeviceDisplayPlanePropertiesKHR',
-                      'vkGetDisplayPlaneSupportedDisplaysKHR',
-                      'vkGetDisplayModePropertiesKHR',
-                      'vkCreateDisplayModeKHR',
-                      'vkGetDisplayPlaneCapabilitiesKHR',
-                      'vkCreateDisplayPlaneSurfaceKHR']
-        if self.wsi == 'Win32':
-            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
-                                 ('display_enabled', display_wsi_instance_exts),
-                                 ('win32_enabled', ['vkCreateWin32SurfaceKHR'])]
-        elif self.wsi == 'Android':
-            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
-                                 ('android_enabled', ['vkCreateAndroidSurfaceKHR'])]
-        elif self.wsi == 'Xcb' or self.wsi == 'Xlib' or self.wsi == 'Wayland' or self.wsi == 'Mir':
-            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
-                                 ('display_enabled', display_wsi_instance_exts),
-                                 ('xcb_enabled', ['vkCreateXcbSurfaceKHR']),
-                                 ('xlib_enabled', ['vkCreateXlibSurfaceKHR']),
-                                 ('wayland_enabled',  ['vkCreateWaylandSurfaceKHR']),
-                                 ('mir_enabled', ['vkCreateMirSurfaceKHR'])]
-        elif self.wsi == 'Display':
-            instance_extensions=[('wsi_enabled', surface_wsi_instance_exts),
-                                 ('display_enabled', display_wsi_instance_exts)]
-        else:
-            print('Error: Undefined DisplayServer')
-            instance_extensions=[]
-
-        body = ["namespace %s {" % self.layer_name,
-                self._generate_dispatch_entrypoints(),
-                self._generate_layer_introspection_function(),
-                self._generate_layer_gpa_function(extensions,
-                                                  instance_extensions),
-                "} // namespace %s" % self.layer_name,
-                self._gen_layer_interface_v0_functions()]
-        return "\n\n".join(body)
-
-def main():
-    wsi = {
-            "Win32",
-            "Android",
-            "Xcb",
-            "Xlib",
-            "Wayland",
-            "Mir",
-            "Display",
-    }
-
-    subcommands = {
-            "unique_objects" : UniqueObjectsSubcommand,
-    }
-
-    if len(sys.argv) < 4 or sys.argv[1] not in wsi or sys.argv[2] not in subcommands or not os.path.exists(sys.argv[3]):
-        print("Usage: %s <wsi> <subcommand> <input_header> [outdir]" % sys.argv[0])
-        print
-        print("Available subcommands are: %s" % " ".join(subcommands))
-        exit(1)
-
-    hfp = vk_helper.HeaderFileParser(sys.argv[3])
-    hfp.parse()
-    vk_helper.enum_val_dict = hfp.get_enum_val_dict()
-    vk_helper.enum_type_dict = hfp.get_enum_type_dict()
-    vk_helper.struct_dict = hfp.get_struct_dict()
-    vk_helper.typedef_fwd_dict = hfp.get_typedef_fwd_dict()
-    vk_helper.typedef_rev_dict = hfp.get_typedef_rev_dict()
-    vk_helper.types_dict = hfp.get_types_dict()
-
-    outfile = None
-    if len(sys.argv) >= 5:
-        outfile = sys.argv[4]
-
-    subcmd = subcommands[sys.argv[2]](outfile)
-    subcmd.run()
-
-if __name__ == "__main__":
-    main()
diff --git a/vk-layer-introspect b/vk-layer-introspect.py
similarity index 100%
rename from vk-layer-introspect
rename to vk-layer-introspect.py
diff --git a/vk.xml b/vk.xml
index ddf94b0..7fcb2eb 100644
--- a/vk.xml
+++ b/vk.xml
@@ -104,7 +104,7 @@
         <type category="define">// Vulkan 1.0 version number
 #define <name>VK_API_VERSION_1_0</name> <type>VK_MAKE_VERSION</type>(1, 0, 0)</type>    <!-- The patch version here should never be set to anything other than 0 -->
         <type category="define">// Version of this file
-#define <name>VK_HEADER_VERSION</name> 26</type>
+#define <name>VK_HEADER_VERSION</name> 31</type>
 
         <type category="define">
 #define <name>VK_DEFINE_HANDLE</name>(object) typedef struct object##_T* object;</type>
@@ -346,6 +346,7 @@
         <type name="VkRasterizationOrderAMD" category="enum"/>
         <type name="VkExternalMemoryHandleTypeFlagBitsNV" category="enum"/>
         <type name="VkExternalMemoryFeatureFlagBitsNV" category="enum"/>
+        <type name="VkValidationCheckEXT" category="enum"/>
 
         <!-- The PFN_vk*Function types are used by VkAllocationCallbacks below -->
         <type category="funcpointer">typedef void (VKAPI_PTR *<name>PFN_vkInternalAllocationNotification</name>)(
@@ -414,13 +415,6 @@
             <member><type>float</type>          <name>minDepth</name></member>
             <member><type>float</type>          <name>maxDepth</name></member>
             <validity>
-                <usage>pname:width must: be greater than `0.0` and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[0]</usage>
-                <usage>pname:height must: be greater than `0.0` and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxViewportDimensions[1]</usage>
-                <usage>pname:x and pname:y must: each be between pname:viewportBoundsRange[0] and pname:viewportBoundsRange[1], inclusive</usage>
-                <usage>pname:x + pname:width must: be less than or equal to pname:viewportBoundsRange[1]</usage>
-                <usage>pname:y + pname:height must: be less than or equal to pname:viewportBoundsRange[1]</usage>
-                <usage>pname:minDepth must: be between `0.0` and `1.0`, inclusive</usage>
-                <usage>pname:maxDepth must: be between `0.0` and `1.0`, inclusive</usage>
             </validity>
         </type>
         <type category="struct" name="VkRect2D">
@@ -472,7 +466,6 @@
             <member><type>uint32_t</type>        <name>engineVersion</name></member>
             <member><type>uint32_t</type>        <name>apiVersion</name></member>
             <validity>
-                <usage>pname:apiVersion must: be zero, or otherwise it must: be a version that the implementation supports, or supports an effective substitute for</usage>
             </validity>
         </type>
         <type category="struct" name="VkAllocationCallbacks">
@@ -483,10 +476,6 @@
             <member optional="true"><type>PFN_vkInternalAllocationNotification</type> <name>pfnInternalAllocation</name></member>
             <member optional="true"><type>PFN_vkInternalFreeNotification</type> <name>pfnInternalFree</name></member>
             <validity>
-                <usage>pname:pfnAllocation must: be a pointer to a valid user-defined PFN_vkAllocationFunction</usage>
-                <usage>pname:pfnReallocation must: be a pointer to a valid user-defined PFN_vkReallocationFunction</usage>
-                <usage>pname:pfnFree must: be a pointer to a valid user-defined PFN_vkFreeFunction</usage>
-                <usage>If either of pname:pfnInternalAllocation or pname:pfnInternalFree is not `NULL`, both must: be valid callbacks</usage>
             </validity>
         </type>
         <type category="struct" name="VkDeviceQueueCreateInfo">
@@ -497,9 +486,6 @@
             <member><type>uint32_t</type>        <name>queueCount</name></member>
             <member len="queueCount">const <type>float</type>*    <name>pQueuePriorities</name></member>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties</usage>
-                <usage>pname:queueCount must: be less than or equal to the pname:queueCount member of the sname:VkQueueFamilyProperties structure, as returned by fname:vkGetPhysicalDeviceQueueFamilyProperties in the pname:pQueueFamilyProperties[pname:queueFamilyIndex]</usage>
-                <usage>Each element of pname:pQueuePriorities must: be between `0.0` and `1.0` inclusive</usage>
             </validity>
         </type>
         <type category="struct" name="VkDeviceCreateInfo">
@@ -514,7 +500,6 @@
             <member len="enabledExtensionCount,null-terminated">const <type>char</type>* const*      <name>ppEnabledExtensionNames</name></member>
             <member optional="true">const <type>VkPhysicalDeviceFeatures</type>* <name>pEnabledFeatures</name></member>
             <validity>
-                <usage>The pname:queueFamilyIndex member of any given element of pname:pQueueCreateInfos must: be unique within pname:pQueueCreateInfos</usage>
             </validity>
         </type>
         <type category="struct" name="VkInstanceCreateInfo">
@@ -547,8 +532,6 @@
             <member><type>VkDeviceSize</type>           <name>allocationSize</name></member>                 <!-- Size of memory allocation -->
             <member><type>uint32_t</type>               <name>memoryTypeIndex</name></member>                <!-- Index of the of the memory type to allocate from -->
             <validity>
-                <usage>pname:allocationSize must: be less than or equal to the amount of memory available to the sname:VkMemoryHeap specified by pname:memoryTypeIndex and the calling command's sname:VkDevice</usage>
-                <usage>pname:allocationSize must: be greater than `0`</usage>
             </validity>
         </type>
         <type category="struct" name="VkMemoryRequirements" returnedonly="true">
@@ -583,11 +566,6 @@
             <member><type>VkDeviceSize</type>           <name>offset</name></member>                         <!-- Offset within the memory object where the range starts -->
             <member><type>VkDeviceSize</type>           <name>size</name></member>                           <!-- Size of the range within the memory object -->
             <validity>
-                <usage>pname:memory must: currently be mapped</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:offset and pname:size must: specify a range contained within the currently mapped range of pname:memory</usage>
-                <usage>If pname:size is equal to ename:VK_WHOLE_SIZE, pname:offset must: be within the currently mapped range of pname:memory</usage>
-                <usage>pname:offset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be a multiple of sname:VkPhysicalDeviceLimits::pname:nonCoherentAtomSize</usage>
             </validity>
         </type>
         <type category="struct" name="VkFormatProperties" returnedonly="true">
@@ -607,9 +585,6 @@
             <member><type>VkDeviceSize</type>           <name>offset</name></member>                         <!-- Base offset from buffer start in bytes to update in the descriptor set. -->
             <member><type>VkDeviceSize</type>           <name>range</name></member>                          <!-- Size in bytes of the buffer resource for this descriptor update. -->
             <validity>
-                <usage>pname:offset must: be less than the size of pname:buffer</usage>
-                <usage>If pname:range is not equal to ename:VK_WHOLE_SIZE, pname:range must: be greater than `0`</usage>
-                <usage>If pname:range is not equal to ename:VK_WHOLE_SIZE, pname:range must: be less than or equal to the size of pname:buffer minus pname:offset</usage>
             </validity>
         </type>
         <type category="struct" name="VkDescriptorImageInfo">
@@ -629,23 +604,6 @@
             <member noautovalidity="true" len="descriptorCount">const <type>VkDescriptorBufferInfo</type>* <name>pBufferInfo</name></member>             <!-- Raw buffer, size, and offset for {UNIFORM,STORAGE}_BUFFER[_DYNAMIC] descriptor types. -->
             <member noautovalidity="true" len="descriptorCount">const <type>VkBufferView</type>*    <name>pTexelBufferView</name></member>               <!-- Buffer view to write to the descriptor for {UNIFORM,STORAGE}_TEXEL_BUFFER descriptor types. -->
             <validity>
-                <usage>pname:dstBinding must: be a valid binding point within pname:dstSet</usage>
-                <usage>pname:descriptorType must: match the type of pname:dstBinding within pname:dstSet</usage>
-                <usage>The sum of pname:dstArrayElement and pname:descriptorCount must: be less than or equal to the number of array elements in the descriptor set binding specified by pname:dstBinding, and all applicable consecutive bindings, as described by &lt;&lt;descriptorsets-updates-consecutive&gt;&gt;</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER, ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, pname:pImageInfo must: be a pointer to an array of pname:descriptorCount valid sname:VkDescriptorImageInfo structures</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER or ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, pname:pTexelBufferView must: be a pointer to an array of pname:descriptorCount valid sname:VkBufferView handles</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, or ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, pname:pBufferInfo must: be a pointer to an array of pname:descriptorCount valid sname:VkDescriptorBufferInfo structures</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER or ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and pname:dstSet was not allocated with a layout that included immutable samplers for pname:dstBinding with pname:descriptorType, the pname:sampler member of any given element of pname:pImageInfo must: be a valid sname:VkSampler object</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, or ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the pname:imageView and pname:imageLayout members of any given element of pname:pImageInfo must: be a valid sname:VkImageView and elink:VkImageLayout, respectively</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:offset member of any given element of pname:pBufferInfo must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minUniformBufferOffsetAlignment</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:offset member of any given element of pname:pBufferInfo must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minStorageBufferOffsetAlignment</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:buffer member of any given element of pname:pBufferInfo must: have been created with ename:VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT set</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:buffer member of any given element of pname:pBufferInfo must: have been created with ename:VK_BUFFER_USAGE_STORAGE_BUFFER_BIT set</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER or ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, the pname:range member of any given element of pname:pBufferInfo, or the effective range if pname:range is ename:VK_WHOLE_SIZE, must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxUniformBufferRange</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER or ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, the pname:range member of any given element of pname:pBufferInfo, or the effective range if pname:range is ename:VK_WHOLE_SIZE, must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxStorageBufferRange</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, the sname:VkBuffer that any given element of pname:pTexelBufferView was created from must: have been created with ename:VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT set</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, the sname:VkBuffer that any given element of pname:pTexelBufferView was created from must: have been created with ename:VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT set</usage>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE or ename:VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, the pname:imageView member of any given element of pname:pImageInfo must: have been created with the identity swizzle</usage>
             </validity>
         </type>
         <type category="struct" name="VkCopyDescriptorSet">
@@ -659,11 +617,6 @@
             <member><type>uint32_t</type>               <name>dstArrayElement</name></member>               <!-- Array element within the destination binding to copy to -->
             <member><type>uint32_t</type>               <name>descriptorCount</name></member>                <!-- Number of descriptors to write (determines the size of the array pointed by pDescriptors) -->
             <validity>
-                <usage>pname:srcBinding must: be a valid binding within pname:srcSet</usage>
-                <usage>The sum of pname:srcArrayElement and pname:descriptorCount must: be less than or equal to the number of array elements in the descriptor set binding specified by pname:srcBinding, and all applicable consecutive bindings, as described by &lt;&lt;descriptorsets-updates-consecutive&gt;&gt;</usage>
-                <usage>pname:dstBinding must: be a valid binding within pname:dstSet</usage>
-                <usage>The sum of pname:dstArrayElement and pname:descriptorCount must: be less than or equal to the number of array elements in the descriptor set binding specified by pname:dstBinding, and all applicable consecutive bindings, as described by &lt;&lt;descriptorsets-updates-consecutive&gt;&gt;</usage>
-                <usage>If pname:srcSet is equal to pname:dstSet, then the source and destination ranges of descriptors must: not overlap, where the ranges may: include array elements from consecutive bindings as described by &lt;&lt;descriptorsets-updates-consecutive&gt;&gt;</usage>
             </validity>
         </type>
         <type category="struct" name="VkBufferCreateInfo">
@@ -676,13 +629,6 @@
             <member optional="true"><type>uint32_t</type>               <name>queueFamilyIndexCount</name></member>
             <member noautovalidity="true" len="queueFamilyIndexCount">const <type>uint32_t</type>*        <name>pQueueFamilyIndices</name></member>
             <validity>
-                <usage>pname:size must: be greater than `0`</usage>
-                <usage>If pname:sharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:pQueueFamilyIndices must: be a pointer to an array of pname:queueFamilyIndexCount basetype:uint32_t values</usage>
-                <usage>If pname:sharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:queueFamilyIndexCount must: be greater than `1`</usage>
-                <usage>If the &lt;&lt;features-features-sparseBinding,sparse bindings&gt;&gt; feature is not enabled, pname:flags must: not contain ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidencyBuffer,sparse buffer residency&gt;&gt; feature is not enabled, pname:flags must: not contain ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidencyAliased,sparse aliased residency&gt;&gt; feature is not enabled, pname:flags must: not contain ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT</usage>
-                <usage>If pname:flags contains ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT or ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must: also contain ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT</usage>
             </validity>
         </type>
         <type category="struct" name="VkBufferViewCreateInfo">
@@ -693,26 +639,12 @@
             <member><type>VkFormat</type>               <name>format</name></member>                         <!-- Optionally specifies format of elements -->
             <member><type>VkDeviceSize</type>           <name>offset</name></member>                         <!-- Specified in bytes -->
             <member><type>VkDeviceSize</type>           <name>range</name></member>                          <!-- View size specified in bytes -->
-            <validity>
-                <usage>pname:offset must: be less than the size of pname:buffer</usage>
-                <usage>pname:offset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minTexelBufferOffsetAlignment</usage>
-                <usage>If pname:range is not equal to ename:VK_WHOLE_SIZE:
-                        ** pname:range must: be greater than `0`
-                        ** pname:range must: be a multiple of the element size of pname:format
-                        ** pname:range divided by the size of an element of pname:format, must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxTexelBufferElements
-                        ** the sum of pname:offset and pname:range must: be less than or equal to the size of pname:buffer</usage>
-                <usage>pname:buffer must: have been created with a pname:usage value containing at least one of ename:VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or ename:VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT</usage>
-                <usage>If pname:buffer was created with pname:usage containing ename:VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, pname:format must: be supported for uniform texel buffers, as specified by the ename:VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT flag in sname:VkFormatProperties::pname:bufferFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage>If pname:buffer was created with pname:usage containing ename:VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, pname:format must: be supported for storage texel buffers, as specified by the ename:VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT flag in sname:VkFormatProperties::pname:bufferFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-            </validity>
         </type>
         <type category="struct" name="VkImageSubresource">
             <member><type>VkImageAspectFlags</type>     <name>aspectMask</name></member>
             <member><type>uint32_t</type>               <name>mipLevel</name></member>
             <member><type>uint32_t</type>               <name>arrayLayer</name></member>
             <validity>
-                <usage>pname:mipLevel must: be less than the pname:mipLevels specified in slink:VkImageCreateInfo when the image was created</usage>
-                <usage>pname:arrayLayer must: be less than the pname:arrayLayers specified in slink:VkImageCreateInfo when the image was created</usage>
             </validity>
         </type>
         <type category="struct" name="VkImageSubresourceLayers">
@@ -721,10 +653,6 @@
             <member><type>uint32_t</type>               <name>baseArrayLayer</name></member>
             <member><type>uint32_t</type>               <name>layerCount</name></member>
             <validity>
-                <usage>If pname:aspectMask contains ename:VK_IMAGE_ASPECT_COLOR_BIT, it must: not contain either of ename:VK_IMAGE_ASPECT_DEPTH_BIT or ename:VK_IMAGE_ASPECT_STENCIL_BIT</usage>
-                <usage>pname:aspectMask must: not contain ename:VK_IMAGE_ASPECT_METADATA_BIT</usage>
-                <usage>pname:mipLevel must: be less than the pname:mipLevels specified in slink:VkImageCreateInfo when the image was created</usage>
-                <usage>latexmath:[$(baseArrayLayer + layerCount)$] must: be less than or equal to the pname:arrayLayers specified in slink:VkImageCreateInfo when the image was created</usage>
             </validity>
         </type>
         <type category="struct" name="VkImageSubresourceRange">
@@ -734,8 +662,6 @@
             <member><type>uint32_t</type>               <name>baseArrayLayer</name></member>
             <member><type>uint32_t</type>               <name>layerCount</name></member>
             <validity>
-                <usage>If pname:levelCount is not ename:VK_REMAINING_MIP_LEVELS, latexmath:[$(baseMipLevel + levelCount)$] must: be less than or equal to the pname:mipLevels specified in slink:VkImageCreateInfo when the image was created</usage>
-                <usage>If pname:layerCount is not ename:VK_REMAINING_ARRAY_LAYERS, latexmath:[$(baseArrayLayer + layerCount)$] must: be less than or equal to the pname:arrayLayers specified in slink:VkImageCreateInfo when the image was created</usage>
             </validity>
         </type>
         <type category="struct" name="VkMemoryBarrier">
@@ -755,12 +681,6 @@
             <member><type>VkDeviceSize</type>           <name>offset</name></member>                         <!-- Offset within the buffer to sync -->
             <member><type>VkDeviceSize</type>           <name>size</name></member>                           <!-- Amount of bytes to sync -->
             <validity>
-                <usage>pname:offset must: be less than the size of pname:buffer</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be greater than `0`</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be less than or equal to than the size of pname:buffer minus pname:offset</usage>
-                <usage>If pname:buffer was created with a sharing mode of ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED</usage>
-                <usage>If pname:buffer was created with a sharing mode of ename:VK_SHARING_MODE_EXCLUSIVE, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: either both be ename:VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see &lt;&lt;devsandqueues-queueprops&gt;&gt;)</usage>
-                <usage>If pname:buffer was created with a sharing mode of ename:VK_SHARING_MODE_EXCLUSIVE, and pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex are valid queue families, at least one of them must: be the same as the family of the queue that will execute this barrier</usage>
             </validity>
         </type>
         <type category="struct" name="VkImageMemoryBarrier">
@@ -775,19 +695,6 @@
             <member><type>VkImage</type>                <name>image</name></member>                          <!-- Image to sync -->
             <member><type>VkImageSubresourceRange</type> <name>subresourceRange</name></member>              <!-- Subresource range to sync -->
             <validity>
-                <usage>pname:oldLayout must: be ename:VK_IMAGE_LAYOUT_UNDEFINED or the current layout of the image subresources affected by the barrier</usage>
-                <usage>pname:newLayout must: not be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED</usage>
-                <usage>If pname:image was created with a sharing mode of ename:VK_SHARING_MODE_CONCURRENT, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: both be ename:VK_QUEUE_FAMILY_IGNORED</usage>
-                <usage>If pname:image was created with a sharing mode of ename:VK_SHARING_MODE_EXCLUSIVE, pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex must: either both be ename:VK_QUEUE_FAMILY_IGNORED, or both be a valid queue family (see &lt;&lt;devsandqueues-queueprops&gt;&gt;)</usage>
-                <usage>If pname:image was created with a sharing mode of ename:VK_SHARING_MODE_EXCLUSIVE, and pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex are valid queue families, at least one of them must: be the same as the family of the queue that will execute this barrier</usage>
-                <usage>pname:subresourceRange must: be a valid image subresource range for the image (see &lt;&lt;resources-image-views&gt;&gt;)</usage>
-                <usage>If pname:image has a depth/stencil format with both depth and stencil components, then pname:aspectMask member of pname:subresourceRange must: include both ename:VK_IMAGE_ASPECT_DEPTH_BIT and ename:VK_IMAGE_ASPECT_STENCIL_BIT</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_SAMPLED_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT set</usage>
-                <usage>If either pname:oldLayout or pname:newLayout is ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then pname:image must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT set</usage>
             </validity>
         </type>
         <type category="struct" name="VkImageCreateInfo">
@@ -807,50 +714,6 @@
             <member noautovalidity="true" len="queueFamilyIndexCount">const <type>uint32_t</type>*        <name>pQueueFamilyIndices</name></member>            <!-- Array of queue family indices to share across -->
             <member><type>VkImageLayout</type>          <name>initialLayout</name></member>                  <!-- Initial image layout for all subresources -->
             <validity>
-                <usage>If pname:sharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:pQueueFamilyIndices must: be a pointer to an array of pname:queueFamilyIndexCount basetype:uint32_t values</usage>
-                <usage>If pname:sharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:queueFamilyIndexCount must: be greater than `1`</usage>
-                <usage>pname:format must: not be ename:VK_FORMAT_UNDEFINED</usage>
-                <usage>The pname:width, pname:height, and pname:depth members of pname:extent must: all be greater than `0`</usage>
-                <usage>pname:mipLevels must: be greater than `0`</usage>
-                <usage>pname:arrayLayers must: be greater than `0`</usage>
-                <usage>If pname:flags contains ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, pname:imageType must be ename:VK_IMAGE_TYPE_2D</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_1D, pname:extent.width must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageDimension1D, or sname:VkImageFormatProperties::pname:maxExtent.width (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_2D and pname:flags does not contain ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, pname:extent.width and pname:extent.height must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageDimension2D, or sname:VkImageFormatProperties::pname:maxExtent.width/height (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_2D and pname:flags contains ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, pname:extent.width and pname:extent.height must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageDimensionCube, or sname:VkImageFormatProperties::pname:maxExtent.width/height (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_2D and pname:flags contains ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, pname:extent.width and pname:extent.height must: be equal and pname:arrayLayers must: be greater than or equal to 6</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_3D, pname:extent.width, pname:extent.height and pname:extent.depth must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageDimension3D, or sname:VkImageFormatProperties::pname:maxExtent.width/height/depth (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_1D, both pname:extent.height and pname:extent.depth must: be `1`</usage>
-                <usage>If pname:imageType is ename:VK_IMAGE_TYPE_2D, pname:extent.depth must: be `1`</usage>
-                <usage>pname:mipLevels must: be less than or equal to latexmath:[$\lfloor\log_2(\max(\mathit{extent.width}, \mathit{extent.height}, \mathit{extent.depth}))\rfloor + 1$]</usage>
-                <usage>If any of pname:extent.width, pname:extent.height, or pname:extent.depth are greater than the equivalently named members of sname:VkPhysicalDeviceLimits::pname:maxImageDimension3D, pname:mipLevels must: be less than or equal to sname:VkImageFormatProperties::pname:maxMipLevels (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure)</usage>
-                <usage>pname:arrayLayers must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxImageArrayLayers, or sname:VkImageFormatProperties::pname:maxArrayLayers (as returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure) - whichever is higher</usage>
-                <usage>If pname:samples is not ename:VK_SAMPLE_COUNT_1_BIT, pname:imageType must: be ename:VK_IMAGE_TYPE_2D, pname:flags must: not contain ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, pname:tiling must: be ename:VK_IMAGE_TILING_OPTIMAL, and pname:mipLevels must: be equal to `1`</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, then bits other than ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, and ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT mustnot: be set</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, pname:extent.width must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferWidth</usage>
-                <usage>If pname:usage includes ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, ename:VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, pname:extent.height must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferHeight</usage>
-                <usage>pname:samples must: be a bit value that is set in sname:VkImageFormatProperties::pname:sampleCounts returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, pname:usage, and pname:flags equal to those in this structure</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionETC2,ETC2 texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, ename:VK_FORMAT_EAC_R11_UNORM_BLOCK, ename:VK_FORMAT_EAC_R11_SNORM_BLOCK, ename:VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or ename:VK_FORMAT_EAC_R11G11_SNORM_BLOCK</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionASTC_LDR,ASTC LDR texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_ASTC_4x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_4x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_12x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or ename:VK_FORMAT_ASTC_12x12_SRGB_BLOCK</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionBC,BC texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_BC1_RGB_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGB_SRGB_BLOCK, ename:VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ename:VK_FORMAT_BC2_UNORM_BLOCK, ename:VK_FORMAT_BC2_SRGB_BLOCK, ename:VK_FORMAT_BC3_UNORM_BLOCK, ename:VK_FORMAT_BC3_SRGB_BLOCK, ename:VK_FORMAT_BC4_UNORM_BLOCK, ename:VK_FORMAT_BC4_SNORM_BLOCK, ename:VK_FORMAT_BC5_UNORM_BLOCK, ename:VK_FORMAT_BC5_SNORM_BLOCK, ename:VK_FORMAT_BC6H_UFLOAT_BLOCK, ename:VK_FORMAT_BC6H_SFLOAT_BLOCK, ename:VK_FORMAT_BC7_UNORM_BLOCK, or ename:VK_FORMAT_BC7_SRGB_BLOCK</usage>
-                <usage>If the &lt;&lt;features-features-shaderStorageImageMultisample,multisampled storage images&gt;&gt; feature is not enabled, and pname:usage contains ename:VK_IMAGE_USAGE_STORAGE_BIT, pname:samples must: be ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseBinding,sparse bindings&gt;&gt; feature is not enabled, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidencyImage2D,sparse residency for 2D images&gt;&gt; feature is not enabled, and pname:imageType is ename:VK_IMAGE_TYPE_2D, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidencyImage3D,sparse residency for 3D images&gt;&gt; feature is not enabled, and pname:imageType is ename:VK_IMAGE_TYPE_3D, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidency2Samples,sparse residency for images with 2 samples&gt;&gt; feature is not enabled, pname:imageType is ename:VK_IMAGE_TYPE_2D, and pname:samples is ename:VK_SAMPLE_COUNT_2_BIT, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidency4Samples,sparse residency for images with 4 samples&gt;&gt; feature is not enabled, pname:imageType is ename:VK_IMAGE_TYPE_2D, and pname:samples is ename:VK_SAMPLE_COUNT_4_BIT, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidency8Samples,sparse residency for images with 8 samples&gt;&gt; feature is not enabled, pname:imageType is ename:VK_IMAGE_TYPE_2D, and pname:samples is ename:VK_SAMPLE_COUNT_8_BIT, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-sparseResidency16Samples,sparse residency for images with 16 samples&gt;&gt; feature is not enabled, pname:imageType is ename:VK_IMAGE_TYPE_2D, and pname:samples is ename:VK_SAMPLE_COUNT_16_BIT, pname:flags must: not contain ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_LINEAR, pname:format must: be a format that has at least one supported feature bit present in the value of sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_LINEAR, and sname:VkFormatProperties::pname:linearTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_SAMPLED_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_LINEAR, and sname:VkFormatProperties::pname:linearTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_STORAGE_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_LINEAR, and sname:VkFormatProperties::pname:linearTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_LINEAR, and sname:VkFormatProperties::pname:linearTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_OPTIMAL, pname:format must: be a format that has at least one supported feature bit present in the value of sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_OPTIMAL, and sname:VkFormatProperties::pname:optimalTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_SAMPLED_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_OPTIMAL, and sname:VkFormatProperties::pname:optimalTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_STORAGE_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_OPTIMAL, and sname:VkFormatProperties::pname:optimalTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</usage>
-                <usage>If pname:tiling is ename:VK_IMAGE_TILING_OPTIMAL, and sname:VkFormatProperties::pname:optimalTilingFeatures (as returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format) does not include ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, pname:usage must: not contain ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</usage>
-                <usage>If pname:flags contains ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT or ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, it must: also contain ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT</usage>
             </validity>
         </type>
         <type category="struct" name="VkSubresourceLayout" returnedonly="true">
@@ -870,25 +733,6 @@
             <member><type>VkComponentMapping</type>     <name>components</name></member>
             <member><type>VkImageSubresourceRange</type> <name>subresourceRange</name></member>
             <validity>
-                <usage>If pname:image was not created with ename:VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT then pname:viewType must: not be ename:VK_IMAGE_VIEW_TYPE_CUBE or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage>If the &lt;&lt;features-features-imageCubeArray,image cubemap arrays&gt;&gt; feature is not enabled, pname:viewType must: not be ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionETC2,ETC2 texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, ename:VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, ename:VK_FORMAT_EAC_R11_UNORM_BLOCK, ename:VK_FORMAT_EAC_R11_SNORM_BLOCK, ename:VK_FORMAT_EAC_R11G11_UNORM_BLOCK, or ename:VK_FORMAT_EAC_R11G11_SNORM_BLOCK</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionASTC_LDR,ASTC LDR texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_ASTC_4x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_4x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x4_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x4_SRGB_BLOCK, ename:VK_FORMAT_ASTC_5x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_5x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_6x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_6x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_8x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_8x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x5_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x5_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x6_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x6_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x8_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x8_SRGB_BLOCK, ename:VK_FORMAT_ASTC_10x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_10x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x10_UNORM_BLOCK, ename:VK_FORMAT_ASTC_12x10_SRGB_BLOCK, ename:VK_FORMAT_ASTC_12x12_UNORM_BLOCK, or ename:VK_FORMAT_ASTC_12x12_SRGB_BLOCK</usage>
-                <usage>If the &lt;&lt;features-features-textureCompressionBC,BC texture compression&gt;&gt; feature is not enabled, pname:format must: not be ename:VK_FORMAT_BC1_RGB_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGB_SRGB_BLOCK, ename:VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ename:VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ename:VK_FORMAT_BC2_UNORM_BLOCK, ename:VK_FORMAT_BC2_SRGB_BLOCK, ename:VK_FORMAT_BC3_UNORM_BLOCK, ename:VK_FORMAT_BC3_SRGB_BLOCK, ename:VK_FORMAT_BC4_UNORM_BLOCK, ename:VK_FORMAT_BC4_SNORM_BLOCK, ename:VK_FORMAT_BC5_UNORM_BLOCK, ename:VK_FORMAT_BC5_SNORM_BLOCK, ename:VK_FORMAT_BC6H_UFLOAT_BLOCK, ename:VK_FORMAT_BC6H_SFLOAT_BLOCK, ename:VK_FORMAT_BC7_UNORM_BLOCK, or ename:VK_FORMAT_BC7_SRGB_BLOCK</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_LINEAR, pname:format must: be format that has at least one supported feature bit present in the value of sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_LINEAR and pname:usage containing ename:VK_IMAGE_USAGE_SAMPLED_BIT, pname:format must: be supported for sampled images, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_LINEAR and pname:usage containing ename:VK_IMAGE_USAGE_STORAGE_BIT, pname:format must: be supported for storage images, as specified by the ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_LINEAR and pname:usage containing ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, pname:format must: be supported for color attachments, as specified by the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_LINEAR and pname:usage containing ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, pname:format must: be supported for depth/stencil attachments, as specified by the ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_OPTIMAL, pname:format must: be format that has at least one supported feature bit present in the value of sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_OPTIMAL and pname:usage containing ename:VK_IMAGE_USAGE_SAMPLED_BIT, pname:format must: be supported for sampled images, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT flag in sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_OPTIMAL and pname:usage containing ename:VK_IMAGE_USAGE_STORAGE_BIT, pname:format must: be supported for storage images, as specified by the ename:VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT flag in sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_OPTIMAL and pname:usage containing ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, pname:format must: be supported for color attachments, as specified by the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>If pname:image was created with ename:VK_IMAGE_TILING_OPTIMAL and pname:usage containing ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, pname:format must: be supported for depth/stencil attachments, as specified by the ename:VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties with the same value of pname:format</usage>
-                <usage>pname:subresourceRange must: be a valid image subresource range for pname:image (see &lt;&lt;resources-image-views&gt;&gt;)</usage>
-                <usage>If pname:image was created with the ename:VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, pname:format must: be compatible with the pname:format used to create pname:image, as defined in &lt;&lt;features-formats-compatibility-classes,Format Compatibility Classes&gt;&gt;</usage>
-                <usage>If pname:image was not created with the ename:VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag, pname:format must: be identical to the pname:format used to create pname:image</usage>
-                <usage>pname:subResourceRange and pname:viewType must: be compatible with the image, as described in the &lt;&lt;resources-image-views-compatibility,compatibility table&gt;&gt;</usage>
             </validity>
         </type>
         <type category="struct" name="VkBufferCopy">
@@ -903,13 +747,6 @@
             <member><type>VkDeviceSize</type>           <name>memoryOffset</name></member>                   <!-- Specified in bytes -->
             <member optional="true"><type>VkSparseMemoryBindFlags</type><name>flags</name></member>                          <!-- Reserved for future -->
             <validity>
-                <usage>If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory and pname:memoryOffset must: match the memory requirements of the resource, as described in section &lt;&lt;resources-association&gt;&gt;</usage>
-                <usage>If pname:memory is not dlink:VK_NULL_HANDLE, pname:memory must: not have been created with a memory type that reports ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT bit set</usage>
-                <usage>pname:size must: be greater than `0`</usage>
-                <usage>pname:resourceOffset must: be less than the size of the resource</usage>
-                <usage>pname:size must: be less than or equal to the size of the resource minus pname:resourceOffset</usage>
-                <usage>pname:memoryOffset must: be less than the size of pname:memory</usage>
-                <usage>pname:size must: be less than or equal to the size of pname:memory minus pname:memoryOffset</usage>
             </validity>
         </type>
         <type category="struct" name="VkSparseImageMemoryBind">
@@ -920,17 +757,8 @@
             <member><type>VkDeviceSize</type>           <name>memoryOffset</name></member>                   <!-- Specified in bytes -->
             <member optional="true"><type>VkSparseMemoryBindFlags</type><name>flags</name></member>                          <!-- Reserved for future -->
             <validity>
-                <usage>If the &lt;&lt;features-features-sparseResidencyAliased,sparse aliased residency&gt;&gt; feature is not enabled, and if any other resources are bound to ranges of pname:memory, the range of pname:memory being bound must: not overlap with those bound ranges</usage>
-                <usage>pname:memory and pname:memoryOffset must: match the memory requirements of the calling command's pname:image, as described in section &lt;&lt;resources-association&gt;&gt;</usage>
-                <usage>pname:subresource must: be a valid image subresource for pname:image (see &lt;&lt;resources-image-views&gt;&gt;)</usage>
-                <usage>pname:offset.x must: be a multiple of the sparse image block width (sname:VkSparseImageFormatProperties::pname:imageGranularity.width) of the image</usage>
-                <usage>pname:extent.width must: either be a multiple of the sparse image block width of the image, or else pname:extent.width + pname:offset.x must: equal the width of the image subresource</usage>
-                <usage>pname:offset.y must: be a multiple of the sparse image block height (sname:VkSparseImageFormatProperties::pname:imageGranularity.height) of the image</usage>
-                <usage>pname:extent.height must: either be a multiple of the sparse image block height of the image, or else pname:extent.height + pname:offset.y must: equal the height of the image subresource</usage>
-                <usage>pname:offset.z must: be a multiple of the sparse image block depth (sname:VkSparseImageFormatProperties::pname:imageGranularity.depth) of the image</usage>
-                <usage>pname:extent.depth must: either be a multiple of the sparse image block depth of the image, or else pname:extent.depth + pname:offset.z must: equal the depth of the image subresource</usage>
             </validity>
-    </type>
+        </type>
         <type category="struct" name="VkSparseBufferMemoryBindInfo">
             <member><type>VkBuffer</type> <name>buffer</name></member>
             <member><type>uint32_t</type>               <name>bindCount</name></member>
@@ -941,7 +769,6 @@
             <member><type>uint32_t</type>               <name>bindCount</name></member>
             <member len="bindCount">const <type>VkSparseMemoryBind</type>* <name>pBinds</name></member>
             <validity>
-                <usage>For any given element of pname:pBinds, if the pname:flags member of that element contains ename:VK_SPARSE_MEMORY_BIND_METADATA_BIT, the binding range defined must: be within the mip tail region of the metadata aspect of pname:image</usage>
             </validity>
         </type>
         <type category="struct" name="VkSparseImageMemoryBindInfo">
@@ -969,30 +796,6 @@
             <member><type>VkImageSubresourceLayers</type> <name>dstSubresource</name></member>
             <member><type>VkOffset3D</type>             <name>dstOffset</name></member>                     <!-- Specified in pixels for both compressed and uncompressed images -->
             <member><type>VkExtent3D</type>             <name>extent</name></member>                         <!-- Specified in pixels for both compressed and uncompressed images -->
-            <validity>
-                <usage>The pname:aspectMask member of pname:srcSubresource and pname:dstSubresource must: match</usage>
-                <usage>The pname:layerCount member of pname:srcSubresource and pname:dstSubresource must: match</usage>
-                <usage>If either of the calling command's pname:srcImage or pname:dstImage parameters are of elink:VkImageType ename:VK_IMAGE_TYPE_3D, the pname:baseArrayLayer and pname:layerCount members of both pname:srcSubresource and pname:dstSubresource must: be `0` and `1`, respectively</usage>
-                <usage>The pname:aspectMask member of pname:srcSubresource must: specify aspects present in the calling command's pname:srcImage</usage>
-                <usage>The pname:aspectMask member of pname:dstSubresource must: specify aspects present in the calling command's pname:dstImage</usage>
-                <usage>pname:srcOffset.x and (pname:extent.width + pname:srcOffset.x) must: both be greater than or equal to `0` and less than or equal to the source image subresource width</usage>
-                <usage>pname:srcOffset.y and (pname:extent.height + pname:srcOffset.y) must: both be greater than or equal to `0` and less than or equal to the source image subresource height</usage>
-                <usage>pname:srcOffset.z and (pname:extent.depth + pname:srcOffset.z) must: both be greater than or equal to `0` and less than or equal to the source image subresource depth</usage>
-                <usage>pname:dstOffset.x and (pname:extent.width + pname:dstOffset.x) must: both be greater than or equal to `0` and less than or equal to the destination image subresource width</usage>
-                <usage>pname:dstOffset.y and (pname:extent.height + pname:dstOffset.y) must: both be greater than or equal to `0` and less than or equal to the destination image subresource height</usage>
-                <usage>pname:dstOffset.z and (pname:extent.depth + pname:dstOffset.z) must: both be greater than or equal to `0` and less than or equal to the destination image subresource depth</usage>
-                <usage>If the calling command's pname:srcImage is a compressed format image:
-                        ** all members of pname:srcOffset must: be a multiple of the corresponding dimensions of the compressed texel block
-                        ** pname:extent.width must: be a multiple of the compressed texel block width or (pname:extent.width + pname:srcOffset.x) must: equal the source image subresource width
-                        ** pname:extent.height must: be a multiple of the compressed texel block height or (pname:extent.height + pname:srcOffset.y) must: equal the source image subresource height
-                        ** pname:extent.depth must: be a multiple of the compressed texel block depth or (pname:extent.depth + pname:srcOffset.z) must: equal the source image subresource depth</usage>
-                <usage>If the calling command's pname:dstImage is a compressed format image:
-                        ** all members of pname:dstOffset must: be a multiple of the corresponding dimensions of the compressed texel block
-                        ** pname:extent.width must: be a multiple of the compressed texel block width or (pname:extent.width + pname:dstOffset.x) must: equal the destination image subresource width
-                        ** pname:extent.height must: be a multiple of the compressed texel block height or (pname:extent.height + pname:dstOffset.y) must: equal the destination image subresource height
-                        ** pname:extent.depth must: be a multiple of the compressed texel block depth or (pname:extent.depth + pname:dstOffset.z) must: equal the destination image subresource depth</usage>
-                <usage>pname:srcOffset, pname:dstOffset, and pname:extent must: respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in &lt;&lt;devsandqueues-physical-device-enumeration,Physical Device Enumeration&gt;&gt;</usage>
-            </validity>
         </type>
         <type category="struct" name="VkImageBlit">
             <member><type>VkImageSubresourceLayers</type> <name>srcSubresource</name></member>
@@ -1000,18 +803,6 @@
             <member><type>VkImageSubresourceLayers</type> <name>dstSubresource</name></member>
             <member><type>VkOffset3D</type>             <name>dstOffsets</name>[2]</member>                     <!-- Specified in pixels for both compressed and uncompressed images -->
             <validity>
-                <usage>The pname:aspectMask member of pname:srcSubresource and pname:dstSubresource must: match</usage>
-                <usage>The pname:layerCount member of pname:srcSubresource and pname:dstSubresource must: match</usage>
-                <usage>If either of the calling command's pname:srcImage or pname:dstImage parameters are of elink:VkImageType ename:VK_IMAGE_TYPE_3D, the pname:baseArrayLayer and pname:layerCount members of both pname:srcSubresource and pname:dstSubresource must: be `0` and `1`, respectively</usage>
-                <usage>The pname:aspectMask member of pname:srcSubresource must: specify aspects present in the calling command's pname:srcImage</usage>
-                <usage>The pname:aspectMask member of pname:dstSubresource must: specify aspects present in the calling command's pname:dstImage</usage>
-                <usage>The pname:layerCount member of pname:dstSubresource must: be equal to the pname:layerCount member of pname:srcSubresource</usage>
-                <usage>pname:srcOffset[0].x and pname:srcOffset[1].x must: both be greater than or equal to `0` and less than or equal to the source image subresource width</usage>
-                <usage>pname:srcOffset[0].y and pname:srcOffset[1].y must: both be greater than or equal to `0` and less than or equal to the source image subresource height</usage>
-                <usage>pname:srcOffset[0].z and pname:srcOffset[1].z must: both be greater than or equal to `0` and less than or equal to the source image subresource depth</usage>
-                <usage>pname:dstOffset[0].x and pname:dstOffset[1].x must: both be greater than or equal to `0` and less than or equal to the destination image subresource width</usage>
-                <usage>pname:dstOffset[0].y and pname:dstOffset[1].y must: both be greater than or equal to `0` and less than or equal to the destination image subresource height</usage>
-                <usage>pname:dstOffset[0].z and pname:dstOffset[1].z must: both be greater than or equal to `0` and less than or equal to the destination image subresource depth</usage>
             </validity>
         </type>
         <type category="struct" name="VkBufferImageCopy">
@@ -1022,25 +813,6 @@
             <member><type>VkOffset3D</type>             <name>imageOffset</name></member>                    <!-- Specified in pixels for both compressed and uncompressed images -->
             <member><type>VkExtent3D</type>             <name>imageExtent</name></member>                    <!-- Specified in pixels for both compressed and uncompressed images -->
             <validity>
-                <usage>pname:bufferOffset must: be a multiple of the calling command's sname:VkImage parameter's texel size</usage>
-                <usage>pname:bufferOffset must: be a multiple of `4`</usage>
-                <usage>pname:bufferRowLength must: be `0`, or greater than or equal to the pname:width member of pname:imageExtent</usage>
-                <usage>pname:bufferImageHeight must: be `0`, or greater than or equal to the pname:height member of pname:imageExtent</usage>
-                <usage>pname:imageOffset.x and (pname:imageExtent.width + pname:imageOffset.x) must: both be greater than or equal to `0` and less than or equal to the image subresource width</usage>
-                <usage>pname:imageOffset.y and (imageExtent.height + pname:imageOffset.y) must: both be greater than or equal to `0` and less than or equal to the image subresource height</usage>
-                <usage>pname:imageOffset.z and (imageExtent.depth + pname:imageOffset.z) must: both be greater than or equal to `0` and less than or equal to the image subresource depth</usage>
-                <usage>If the calling command's sname:VkImage parameter is a compressed format image:
-                        ** pname:bufferRowLength must: be a multiple of the compressed texel block width
-                        ** pname:bufferImageHeight must: be a multiple of the compressed texel block height
-                        ** all members of pname:imageOffset must: be a multiple of the corresponding dimensions of the compressed texel block
-                        ** pname:bufferOffset must: be a multiple of the compressed texel block size in bytes
-                        ** pname:imageExtent.width must: be a multiple of the compressed texel block width or (pname:imageExtent.width + pname:imageOffset.x) must: equal the image subresource width
-                        ** pname:imageExtent.height must: be a multiple of the compressed texel block height or (pname:imageExtent.height + pname:imageOffset.y) must: equal the image subresource height
-                        ** pname:imageExtent.depth must: be a multiple of the compressed texel block depth or (pname:imageExtent.depth + pname:imageOffset.z) must: equal the image subresource depth</usage>
-                <usage>pname:bufferOffset, pname:bufferRowLength, pname:bufferImageHeight and all members of pname:imageOffset and pname:imageExtent must: respect the image transfer granularity requirements of the queue family that it will be submitted against, as described in &lt;&lt;devsandqueues-physical-device-enumeration,Physical Device Enumeration&gt;&gt;</usage>
-                <usage>The pname:aspectMask member of pname:imageSubresource must: specify aspects present in the calling command's sname:VkImage parameter</usage>
-                <usage>The pname:aspectMask member of pname:imageSubresource must: only have a single bit set</usage>
-                <usage>If the calling command's sname:VkImage parameter is of elink:VkImageType ename:VK_IMAGE_TYPE_3D, the pname:baseArrayLayer and pname:layerCount members of pname:imageSubresource must: be `0` and `1`, respectively</usage>
             </validity>
         </type>
         <type category="struct" name="VkImageResolve">
@@ -1050,9 +822,6 @@
             <member><type>VkOffset3D</type>             <name>dstOffset</name></member>
             <member><type>VkExtent3D</type>             <name>extent</name></member>
             <validity>
-                <usage>The pname:aspectMask member of pname:srcSubresource and pname:dstSubresource must: only contain ename:VK_IMAGE_ASPECT_COLOR_BIT</usage>
-                <usage>The pname:layerCount member of pname:srcSubresource and pname:dstSubresource must: match</usage>
-                <usage>If either of the calling command's pname:srcImage or pname:dstImage parameters are of elink:VkImageType ename:VK_IMAGE_TYPE_3D, the pname:baseArrayLayer and pname:layerCount members of both pname:srcSubresource and pname:dstSubresource must: be `0` and `1`, respectively</usage>
             </validity>
         </type>
         <type category="struct" name="VkShaderModuleCreateInfo">
@@ -1062,13 +831,6 @@
             <member><type>size_t</type>                 <name>codeSize</name></member>                       <!-- Specified in bytes -->
             <member len="latexmath:[$codeSize \over 4$]">const <type>uint32_t</type>*            <name>pCode</name></member>                          <!-- Binary code of size codeSize -->
             <validity>
-                <usage>pname:codeSize must: be greater than 0</usage>
-                <usage>pname:codeSize must: be a multiple of 4. If the +VK_NV_glsl_shader extension+ is enabled and pname:pCode references GLSL code pname:codeSize can be a multiple of 1</usage>
-                <usage>pname:pCode must: point to valid SPIR-V code, formatted and packed as described by the &lt;&lt;Khronos SPIR-V Specification&gt;&gt;. If the +VK_NV_glsl_shader+ extension is enabled pname:pCode can instead reference valid GLSL code and must: be written to the +GL_KHR_vulkan_glsl+ extension specification</usage>
-                <usage>pname:pCode must: adhere to the validation rules described by the &lt;&lt;spirvenv-module-validation, Validation Rules within a Module&gt;&gt; section of the &lt;&lt;spirvenv-capabilities,SPIR-V Environment&gt;&gt; appendix. If the +VK_NV_glsl_shader+ extension is enabled pname:pCode can be valid GLSL code with respect to the +GL_KHR_vulkan_glsl+ GLSL extension specification</usage>
-                <usage>pname:pCode must: declare the code:Shader capability for SPIR-V code</usage>
-                <usage>pname:pCode must: not declare any capability that is not supported by the API, as described by the &lt;&lt;spirvenv-module-validation, Capabilities&gt;&gt; section of the &lt;&lt;spirvenv-capabilities,SPIR-V Environment&gt;&gt; appendix</usage>
-                <usage>If pname:pCode declares any of the capabilities that are listed as not required by the implementation, the relevant feature must: be enabled, as listed in the &lt;&lt;spirvenv-capabilities-table,SPIR-V Environment&gt;&gt; appendix</usage>
             </validity>
         </type>
         <type category="struct" name="VkDescriptorSetLayoutBinding">
@@ -1078,8 +840,6 @@
             <member noautovalidity="true"><type>VkShaderStageFlags</type>     <name>stageFlags</name></member>                     <!-- Shader stages this binding is visible to -->
             <member noautovalidity="true" optional="true" len="descriptorCount">const <type>VkSampler</type>*       <name>pImmutableSamplers</name></member>             <!-- Immutable samplers (used if descriptor type is SAMPLER or COMBINED_IMAGE_SAMPLER, is either NULL or contains count number of elements) -->
             <validity>
-                <usage>If pname:descriptorType is ename:VK_DESCRIPTOR_TYPE_SAMPLER or ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, and pname:descriptorCount is not `0` and pname:pImmutableSamplers is not `NULL`, pname:pImmutableSamplers must: be a pointer to an array of pname:descriptorCount valid sname:VkSampler handles</usage>
-                <usage>If pname:descriptorCount is not `0`, pname:stageFlags must: be a valid combination of elink:VkShaderStageFlagBits values</usage>
             </validity>
         </type>
         <type category="struct" name="VkDescriptorSetLayoutCreateInfo">
@@ -1093,7 +853,6 @@
             <member><type>VkDescriptorType</type>       <name>type</name></member>
             <member><type>uint32_t</type>               <name>descriptorCount</name></member>
             <validity>
-                <usage>pname:descriptorCount must: be greater than `0`</usage>
             </validity>
         </type>
         <type category="struct" name="VkDescriptorPoolCreateInfo">
@@ -1104,7 +863,6 @@
             <member><type>uint32_t</type>               <name>poolSizeCount</name></member>
             <member len="poolSizeCount">const <type>VkDescriptorPoolSize</type>* <name>pPoolSizes</name></member>
             <validity>
-                <usage>pname:maxSets must: be greater than `0`</usage>
             </validity>
         </type>
         <type category="struct" name="VkDescriptorSetAllocateInfo">
@@ -1114,8 +872,6 @@
             <member><type>uint32_t</type>               <name>descriptorSetCount</name></member>
             <member len="descriptorSetCount">const <type>VkDescriptorSetLayout</type>* <name>pSetLayouts</name></member>
             <validity>
-                <usage>pname:descriptorSetCount must: not be greater than the number of sets that are currently available for allocation in pname:descriptorPool</usage>
-                <usage>pname:descriptorPool must: have enough free descriptor capacity remaining to allocate the descriptor sets of the specified layouts</usage>
             </validity>
         </type>
         <type category="struct" name="VkSpecializationMapEntry">
@@ -1123,7 +879,6 @@
             <member><type>uint32_t</type>               <name>offset</name></member>                         <!-- Offset of the value in the data block -->
             <member><type>size_t</type>                 <name>size</name></member>                           <!-- Size in bytes of the SpecConstant -->
             <validity>
-                <usage>For a pname:constantID specialization constant declared in a shader, pname:size must: match the byte size of the pname:constantID. If the specialization constant is of type code:boolean, pname:size must: be the byte size of VkBool32</usage>
             </validity>
         </type>
         <type category="struct" name="VkSpecializationInfo">
@@ -1132,8 +887,6 @@
             <member optional="true"><type>size_t</type>                 <name>dataSize</name></member>                       <!-- Size in bytes of pData -->
             <member len="dataSize">const <type>void</type>*            <name>pData</name></member>                          <!-- Pointer to SpecConstant data -->
             <validity>
-                <usage>The pname:offset member of any given element of pname:pMapEntries must: be less than pname:dataSize</usage>
-                <usage>For any given element of pname:pMapEntries, pname:size must: be less than or equal to pname:dataSize minus pname:offset</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineShaderStageCreateInfo">
@@ -1145,22 +898,6 @@
             <member len="null-terminated">const <type>char</type>*            <name>pName</name></member>                          <!-- Null-terminated entry point name -->
             <member optional="true">const <type>VkSpecializationInfo</type>* <name>pSpecializationInfo</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:stage must: not be ename:VK_SHADER_STAGE_GEOMETRY_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:stage must: not be ename:VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or ename:VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT</usage>
-                <usage>pname:stage must: not be ename:VK_SHADER_STAGE_ALL_GRAPHICS, or ename:VK_SHADER_STAGE_ALL</usage>
-                <usage>pname:pName must: be the name of an code:OpEntryPoint in pname:module with an execution model that matches pname:stage</usage>
-                <usage>If the identified entry point includes any variable in its interface that is declared with the code:ClipDistance code:BuiltIn decoration, that variable must: not have an array size greater than sname:VkPhysicalDeviceLimits::pname:maxClipDistances</usage>
-                <usage>If the identified entry point includes any variable in its interface that is declared with the code:CullDistance code:BuiltIn decoration, that variable must: not have an array size greater than sname:VkPhysicalDeviceLimits::pname:maxCullDistances</usage>
-                <usage>If the identified entry point includes any variables in its interface that are declared with the code:ClipDistance or code:CullDistance code:BuiltIn decoration, those variables must: not have array sizes which sum to more than sname:VkPhysicalDeviceLimits::pname:maxCombinedClipAndCullDistances</usage>
-                <usage>If the identified entry point includes any variable in its interface that is declared with the code:SampleMask code:BuiltIn decoration, that variable must: not have an array size greater than sname:VkPhysicalDeviceLimits::pname:maxSampleMaskWords</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_VERTEX_BIT, the identified entry point must: not include any input variable in its interface that is decorated with code:CullDistance</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT or ename:VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, and the identified entry point has an code:OpExecutionMode instruction that specifies a patch size with code:OutputVertices, the patch size must: be greater than `0` and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxTessellationPatchSize</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must: have an code:OpExecutionMode instruction that specifies a maximum output vertex count that is greater than `0` and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxGeometryOutputVertices</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, the identified entry point must: have an code:OpExecutionMode instruction that specifies an invocation count that is greater than `0` and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxGeometryShaderInvocations</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to code:Layer for any primitive, it must: write the same value to code:Layer for all vertices of a given primitive</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_GEOMETRY_BIT, and the identified entry point writes to code:ViewportIndex for any primitive, it must: write the same value to code:ViewportIndex for all vertices of a given primitive</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_FRAGMENT_BIT, the identified entry point must: not include any output variables in its interface decorated with code:CullDistance</usage>
-                <usage>If pname:stage is ename:VK_SHADER_STAGE_FRAGMENT_BIT, and the identified entry point writes to code:FragDepth in any execution path, it must: write to code:FragDepth in all execution paths</usage>
             </validity>
         </type>
         <type category="struct" name="VkComputePipelineCreateInfo">
@@ -1172,14 +909,6 @@
             <member noautovalidity="true" optional="true"><type>VkPipeline</type>      <name>basePipelineHandle</name></member>             <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
             <member><type>int32_t</type>                <name>basePipelineIndex</name></member>              <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
             <validity>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be dlink:VK_NULL_HANDLE</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, it must: be a valid index into the calling command's pname:pCreateInfos parameter</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, it must: be a valid handle to a compute sname:VkPipeline</usage>
-                <usage>The pname:stage member of pname:stage must: be ename:VK_SHADER_STAGE_COMPUTE_BIT</usage>
-                <usage>The shader code for the entry point identified by pname:stage and the rest of the state identified by this structure must: adhere to the pipeline linking rules described in the &lt;&lt;interfaces,Shader Interfaces&gt;&gt; chapter</usage>
-                <usage>pname:layout must: be &lt;&lt;descriptorsets-pipelinelayout-consistency,consistent&gt;&gt; with all shaders specified in pname:pStages</usage>
             </validity>
         </type>
         <type category="struct" name="VkVertexInputBindingDescription">
@@ -1187,8 +916,6 @@
             <member><type>uint32_t</type>               <name>stride</name></member>                         <!-- Distance between vertices in bytes (0 = no advancement) -->
             <member><type>VkVertexInputRate</type>      <name>inputRate</name></member>                      <!-- The rate at which the vertex data is consumed -->
             <validity>
-                <usage>pname:binding must: be less than sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings</usage>
-                <usage>pname:stride must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindingStride</usage>
             </validity>
         </type>
         <type category="struct" name="VkVertexInputAttributeDescription">
@@ -1197,10 +924,6 @@
             <member><type>VkFormat</type>               <name>format</name></member>                         <!-- format of source data -->
             <member><type>uint32_t</type>               <name>offset</name></member>                         <!-- Offset of first element in bytes from base of vertex -->
             <validity>
-                <usage>pname:location must: be less than sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes</usage>
-                <usage>pname:binding must: be less than sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings</usage>
-                <usage>pname:offset must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributeOffset</usage>
-                <usage>pname:format must: be allowed as a vertex buffer format, as specified by the ename:VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT flag in sname:VkFormatProperties::pname:bufferFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineVertexInputStateCreateInfo">
@@ -1212,12 +935,6 @@
             <member optional="true"><type>uint32_t</type>               <name>vertexAttributeDescriptionCount</name></member> <!-- number of attributes -->
             <member len="vertexAttributeDescriptionCount">const <type>VkVertexInputAttributeDescription</type>* <name>pVertexAttributeDescriptions</name></member>
             <validity>
-                <usage>pname:vertexBindingDescriptionCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings</usage>
-                <usage>pname:vertexAttributeDescriptionCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputAttributes</usage>
-                <usage>For every pname:binding specified by any given element of pname:pVertexAttributeDescriptions, a sname:VkVertexInputBindingDescription must: exist in pname:pVertexBindingDescriptions with the same value of pname:binding</usage>
-                <usage>All elements of pname:pVertexBindingDescriptions must: describe distinct binding numbers</usage>
-                <usage>All elements of pname:pVertexAttributeDescriptions must: describe distinct attribute locations</usage>
-
             </validity>
         </type>
         <type category="struct" name="VkPipelineInputAssemblyStateCreateInfo">
@@ -1227,9 +944,6 @@
             <member><type>VkPrimitiveTopology</type>    <name>topology</name></member>
             <member><type>VkBool32</type>               <name>primitiveRestartEnable</name></member>
             <validity>
-                <usage>If pname:topology is ename:VK_PRIMITIVE_TOPOLOGY_POINT_LIST, ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST, ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pname:primitiveRestartEnable must: be ename:VK_FALSE</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:topology must: not be any of ename:VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, ename:VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or ename:VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:topology must: not be ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineTessellationStateCreateInfo">
@@ -1238,7 +952,6 @@
             <member optional="true"><type>VkPipelineTessellationStateCreateFlags</type>    <name>flags</name></member>        <!-- Reserved -->
             <member><type>uint32_t</type>               <name>patchControlPoints</name></member>
             <validity>
-                <usage>pname:patchControlPoints must: be greater than zero and less than or equal to sname:VkPhysicalDeviceLimits::pname:maxTessellationPatchSize</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineViewportStateCreateInfo">
@@ -1250,11 +963,6 @@
             <member><type>uint32_t</type>               <name>scissorCount</name></member>
             <member noautovalidity="true" optional="true" len="scissorCount">const <type>VkRect2D</type>*        <name>pScissors</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-multiViewport,multiple viewports&gt;&gt; feature is not enabled, pname:viewportCount must: be `1`</usage>
-                <usage>If the &lt;&lt;features-features-multiViewport,multiple viewports&gt;&gt; feature is not enabled, pname:scissorCount must: be `1`</usage>
-                <usage>pname:viewportCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
-                <usage>pname:scissorCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
-                <usage>pname:scissorCount and pname:viewportCount must: be identical</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineRasterizationStateCreateInfo">
@@ -1272,8 +980,6 @@
             <member><type>float</type>                  <name>depthBiasSlopeFactor</name></member>
             <member><type>float</type>                  <name>lineWidth</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-depthClamp,depth clamping&gt;&gt; feature is not enabled, pname:depthClampEnable must: be ename:VK_FALSE</usage>
-                <usage>If the &lt;&lt;features-features-fillModeNonSolid,non-solid fill modes&gt;&gt; feature is not enabled, pname:polygonMode must: be ename:VK_POLYGON_MODE_FILL</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineMultisampleStateCreateInfo">
@@ -1287,9 +993,6 @@
             <member><type>VkBool32</type>               <name>alphaToCoverageEnable</name></member>
             <member><type>VkBool32</type>               <name>alphaToOneEnable</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-sampleRateShading,sample rate shading&gt;&gt; feature is not enabled, pname:sampleShadingEnable must: be ename:VK_FALSE</usage>
-                <usage>If the &lt;&lt;features-features-alphaToOne,alpha to one&gt;&gt; feature is not enabled, pname:alphaToOneEnable must: be ename:VK_FALSE</usage>
-                <usage>pname:minSampleShading must: be in the range latexmath:[$[0,1\]$]</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineColorBlendAttachmentState">
@@ -1302,10 +1005,6 @@
             <member><type>VkBlendOp</type>              <name>alphaBlendOp</name></member>
             <member optional="true"><type>VkColorComponentFlags</type>  <name>colorWriteMask</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-dualSrcBlend,dual source blending&gt;&gt; feature is not enabled, pname:srcColorBlendFactor must: not be ename:VK_BLEND_FACTOR_SRC1_COLOR, ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, ename:VK_BLEND_FACTOR_SRC1_ALPHA, or ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA</usage>
-                <usage>If the &lt;&lt;features-features-dualSrcBlend,dual source blending&gt;&gt; feature is not enabled, pname:dstColorBlendFactor must: not be ename:VK_BLEND_FACTOR_SRC1_COLOR, ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, ename:VK_BLEND_FACTOR_SRC1_ALPHA, or ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA</usage>
-                <usage>If the &lt;&lt;features-features-dualSrcBlend,dual source blending&gt;&gt; feature is not enabled, pname:srcAlphaBlendFactor must: not be ename:VK_BLEND_FACTOR_SRC1_COLOR, ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, ename:VK_BLEND_FACTOR_SRC1_ALPHA, or ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA</usage>
-                <usage>If the &lt;&lt;features-features-dualSrcBlend,dual source blending&gt;&gt; feature is not enabled, pname:dstAlphaBlendFactor must: not be ename:VK_BLEND_FACTOR_SRC1_COLOR, ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, ename:VK_BLEND_FACTOR_SRC1_ALPHA, or ename:VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineColorBlendStateCreateInfo">
@@ -1318,9 +1017,6 @@
             <member len="attachmentCount">const <type>VkPipelineColorBlendAttachmentState</type>* <name>pAttachments</name></member>
             <member><type>float</type>                  <name>blendConstants</name>[4]</member>
             <validity>
-                <usage>If the &lt;&lt;features-features-independentBlend,independent blending&gt;&gt; feature is not enabled, all elements of pname:pAttachments must: be identical</usage>
-                <usage>If the &lt;&lt;features-features-logicOp,logic operations&gt;&gt; feature is not enabled, pname:logicOpEnable must: be ename:VK_FALSE</usage>
-                <usage>If pname:logicOpEnable is ename:VK_TRUE, pname:logicOp must: be a valid elink:VkLogicOp value</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineDynamicStateCreateInfo">
@@ -1353,7 +1049,6 @@
             <member><type>float</type>                  <name>minDepthBounds</name></member>
             <member><type>float</type>                  <name>maxDepthBounds</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-depthBounds,depth bounds testing&gt;&gt; feature is not enabled, pname:depthBoundsTestEnable must: be ename:VK_FALSE</usage>
             </validity>
         </type>
         <type category="struct" name="VkGraphicsPipelineCreateInfo">
@@ -1377,45 +1072,6 @@
             <member noautovalidity="true" optional="true"><type>VkPipeline</type>      <name>basePipelineHandle</name></member>             <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is nonzero, it specifies the handle of the base pipeline this is a derivative of -->
             <member><type>int32_t</type>                <name>basePipelineIndex</name></member>              <!-- If VK_PIPELINE_CREATE_DERIVATIVE_BIT is set and this value is not -1, it specifies an index into pCreateInfos of the base pipeline this is a derivative of -->
             <validity>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, pname:basePipelineHandle must: be dlink:VK_NULL_HANDLE</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineIndex is not `-1`, it must: be a valid index into the calling command's pname:pCreateInfos parameter</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineIndex must: be `-1`</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, pname:basePipelineHandle must: be a valid sname:VkPipeline handle</usage>
-                <usage>If pname:flags contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and pname:basePipelineHandle is not dlink:VK_NULL_HANDLE, it must: be a valid handle to a graphics sname:VkPipeline</usage>
-                <usage>The pname:stage member of each element of pname:pStages must: be unique</usage>
-                <usage>The pname:stage member of one element of pname:pStages must: be ename:VK_SHADER_STAGE_VERTEX_BIT</usage>
-                <usage>The pname:stage member of any given element of pname:pStages must: not be ename:VK_SHADER_STAGE_COMPUTE_BIT</usage>
-                <usage>If pname:pStages includes a tessellation control shader stage, it must: include a tessellation evaluation shader stage</usage>
-                <usage>If pname:pStages includes a tessellation evaluation shader stage, it must: include a tessellation control shader stage</usage>
-                <usage>If pname:pStages includes a tessellation control shader stage and a tessellation evaluation shader stage, pname:pTessellationState must: not be `NULL`</usage>
-                <usage>If pname:pStages includes tessellation shader stages, the shader code of at least one stage must: contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline</usage>
-                <usage>If pname:pStages includes tessellation shader stages, and the shader code of both stages contain an code:OpExecutionMode instruction that specifies the type of subdivision in the pipeline, they must: both specify the same subdivision mode</usage>
-                <usage>If pname:pStages includes tessellation shader stages, the shader code of at least one stage must: contain an code:OpExecutionMode instruction that specifies the output patch size in the pipeline</usage>
-                <usage>If pname:pStages includes tessellation shader stages, and the shader code of both contain an code:OpExecutionMode instruction that specifies the out patch size in the pipeline, they must: both specify the same patch size</usage>
-                <usage>If pname:pStages includes tessellation shader stages, the pname:topology member of pname:pInputAssembly must: be ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST</usage>
-                <usage>If the pname:topology member of pname:pInputAssembly is ename:VK_PRIMITIVE_TOPOLOGY_PATCH_LIST, pname:pStages must: include tessellation shader stages</usage>
-                <usage>If pname:pStages includes a geometry shader stage, and does not include any tessellation shader stages, its shader code must: contain an code:OpExecutionMode instruction that specifies an input primitive type that is &lt;&lt;shaders-geometry-execution, compatible&gt;&gt; with the primitive topology specified in pname:pInputAssembly</usage>
-                <usage>If pname:pStages includes a geometry shader stage, and also includes tessellation shader stages, its shader code must: contain an code:OpExecutionMode instruction that specifies an input primitive type that is &lt;&lt;shaders-geometry-execution, compatible&gt;&gt; with the primitive topology that is output by the tessellation stages</usage>
-                <usage>If pname:pStages includes a fragment shader stage and a geometry shader stage, and the fragment shader code reads from an input variable that is decorated with code:PrimitiveID, then the geometry shader code must: write to a matching output variable, decorated with code:PrimitiveID, in all execution paths</usage>
-                <usage>If pname:pStages includes a fragment shader stage, its shader code must: not read from any input attachment that is defined as ename:VK_ATTACHMENT_UNUSED in pname:subpass</usage>
-                <usage>The shader code for the entry points identified by pname:pStages, and the rest of the state identified by this structure must: adhere to the pipeline linking rules described in the &lt;&lt;interfaces,Shader Interfaces&gt;&gt; chapter</usage>
-                <usage>If pname:subpass uses a depth/stencil attachment in pname:renderpass that has a layout of ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the sname:VkAttachmentReference defined by pname:subpass, and pname:pDepthStencilState is not `NULL`, the pname:depthWriteEnable member of pname:pDepthStencilState must: be ename:VK_FALSE</usage>
-                <usage>If pname:subpass uses a depth/stencil attachment in pname:renderpass that has a layout of ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL in the sname:VkAttachmentReference defined by pname:subpass, and pname:pDepthStencilState is not `NULL`, the pname:failOp, pname:passOp and pname:depthFailOp members of each of the pname:front and pname:back members of pname:pDepthStencilState must: be ename:VK_STENCIL_OP_KEEP</usage>
-                <usage>If pname:pColorBlendState is not `NULL`, the pname:blendEnable member of each element of the pname:pAttachment member of pname:pColorBlendState must: be ename:VK_FALSE if the pname:format of the attachment referred to in pname:subpass of pname:renderPass does not support color blend operations, as specified by the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures or sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage>If pname:pColorBlendState is not `NULL`, The pname:attachmentCount member of pname:pColorBlendState must: be equal to the pname:colorAttachmentCount used to create pname:subpass</usage>
-                <usage>If no element of the pname:pDynamicStates member of pname:pDynamicState is ename:VK_DYNAMIC_STATE_VIEWPORT, the pname:pViewports member of pname:pViewportState must: be a pointer to an array of pname:pViewportState->viewportCount sname:VkViewport structures</usage>
-                <usage>If no element of the pname:pDynamicStates member of pname:pDynamicState is ename:VK_DYNAMIC_STATE_SCISSOR, the pname:pScissors member of pname:pViewportState must: be a pointer to an array of pname:pViewportState->scissorCount sname:VkRect2D structures</usage>
-                <usage>If the wide lines feature is not enabled, and no element of the pname:pDynamicStates member of pname:pDynamicState is ename:VK_DYNAMIC_STATE_LINE_WIDTH, the pname:lineWidth member of pname:pRasterizationState must: be `1.0`</usage>
-                <usage>If the pname:rasterizerDiscardEnable member of pname:pRasterizationState is ename:VK_FALSE, pname:pViewportState must: be a pointer to a valid sname:VkPipelineViewportStateCreateInfo structure</usage>
-                <usage>If the pname:rasterizerDiscardEnable member of pname:pRasterizationState is ename:VK_FALSE, pname:pMultisampleState must: be a pointer to a valid sname:VkPipelineMultisampleStateCreateInfo structure</usage>
-                <usage>If the pname:rasterizerDiscardEnable member of pname:pRasterizationState is ename:VK_FALSE, and pname:subpass uses a depth/stencil attachment, pname:pDepthStencilState must: be a pointer to a valid sname:VkPipelineDepthStencilStateCreateInfo structure</usage>
-                <usage>If the pname:rasterizerDiscardEnable member of pname:pRasterizationState is ename:VK_FALSE, and pname:subpass uses color attachments, pname:pColorBlendState must: be a pointer to a valid sname:VkPipelineColorBlendStateCreateInfo structure</usage>
-                <usage>If the depth bias clamping feature is not enabled, no element of the pname:pDynamicStates member of pname:pDynamicState is ename:VK_DYNAMIC_STATE_DEPTH_BIAS, and the pname:depthBiasEnable member of pname:pDepthStencil is ename:VK_TRUE, the pname:depthBiasClamp member of pname:pDepthStencil must: be `0.0`</usage>
-                <usage>If no element of the pname:pDynamicStates member of pname:pDynamicState is ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS, and the pname:depthBoundsTestEnable member of pname:pDepthStencil is ename:VK_TRUE, the pname:minDepthBounds and pname:maxDepthBounds members of pname:pDepthStencil must: be between `0.0` and `1.0`, inclusive</usage>
-                <usage>pname:layout must: be &lt;&lt;descriptorsets-pipelinelayout-consistency,consistent&gt;&gt; with all shaders specified in pname:pStages</usage>
-                <usage>If pname:subpass uses color and/or depth/stencil attachments, then the pname:rasterizationSamples member of pname:pMultisampleState must: be the same as the sample count for those subpass attachments</usage>
-                <usage>If pname:subpass does not use any color and/or depth/stencil attachments, then the pname:rasterizationSamples member of pname:pMultisampleState must: follow the rules for a &lt;&lt;renderpass-noattachments, zero-attachment subpass&gt;&gt;</usage>
-                <usage>pname:subpass must: be a valid subpass within pname:renderpass</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineCacheCreateInfo">
@@ -1425,8 +1081,6 @@
             <member optional="true"><type>size_t</type>                 <name>initialDataSize</name></member>                <!-- Size of initial data to populate cache, in bytes -->
             <member len="initialDataSize">const <type>void</type>*            <name>pInitialData</name></member>                    <!-- Initial data to populate cache -->
             <validity>
-                <usage>If pname:initialDataSize is not `0`, it must: be equal to the size of pname:pInitialData, as returned by fname:vkGetPipelineCacheData when pname:pInitialData was originally retrieved</usage>
-                <usage>If pname:initialDataSize is not `0`, pname:pInitialData must: have been retrieved from a previous call to fname:vkGetPipelineCacheData</usage>
             </validity>
         </type>
         <type category="struct" name="VkPushConstantRange">
@@ -1434,10 +1088,6 @@
             <member><type>uint32_t</type>               <name>offset</name></member>                         <!-- Start of the range, in bytes -->
             <member><type>uint32_t</type>               <name>size</name></member>                           <!-- Size of the range, in bytes -->
             <validity>
-                <usage>pname:offset must: be less than sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize</usage>
-                <usage>pname:size must: be greater than `0`</usage>
-                <usage>pname:size must: be a multiple of `4`</usage>
-                <usage>pname:size must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus pname:offset</usage>
             </validity>
         </type>
         <type category="struct" name="VkPipelineLayoutCreateInfo">
@@ -1449,12 +1099,6 @@
             <member optional="true"><type>uint32_t</type>               <name>pushConstantRangeCount</name></member>         <!-- Number of push-constant ranges used by the pipeline -->
             <member len="pushConstantRangeCount">const <type>VkPushConstantRange</type>* <name>pPushConstantRanges</name></member>        <!-- Array of pushConstantRangeCount number of ranges used by various shader stages -->
             <validity>
-                <usage>pname:setLayoutCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxBoundDescriptorSets</usage>
-                <usage>The total number of descriptors of the type ename:VK_DESCRIPTOR_TYPE_SAMPLER and ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER accessible to any given shader stage across all elements of pname:pSetLayouts must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorSamplers</usage>
-                <usage>The total number of descriptors of the type ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER and ename:VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pname:pSetLayouts must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorUniformBuffers</usage>
-                <usage>The total number of descriptors of the type ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER and ename:VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC accessible to any given shader stage across all elements of pname:pSetLayouts must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorStorageBuffers</usage>
-                <usage>The total number of descriptors of the type ename:VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, ename:VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, and ename:VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER accessible to any given shader stage across all elements of pname:pSetLayouts must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorSampledImages</usage>
-                <usage>The total number of descriptors of the type ename:VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, and ename:VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER accessible to any given shader stage across all elements of pname:pSetLayouts must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPerStageDescriptorStorageImages</usage>
             </validity>
         </type>
         <type category="struct" name="VkSamplerCreateInfo">
@@ -1477,18 +1121,6 @@
             <member noautovalidity="true"><type>VkBorderColor</type>          <name>borderColor</name></member>
             <member><type>VkBool32</type>               <name>unnormalizedCoordinates</name></member>
             <validity>
-                <usage>The absolute value of pname:mipLodBias must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxSamplerLodBias</usage>
-                <usage>If the &lt;&lt;features-features-samplerAnisotropy,anisotropic sampling&gt;&gt; feature is not enabled, pname:anisotropyEnable must: be ename:VK_FALSE</usage>
-                <usage>If pname:anisotropyEnable is ename:VK_TRUE, pname:maxAnisotropy must: be between `1.0` and sname:VkPhysicalDeviceLimits::pname:maxSamplerAnisotropy, inclusive</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:minFilter and pname:magFilter must: be equal</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:mipmapMode must: be ename:VK_SAMPLER_MIPMAP_MODE_NEAREST</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:minLod and pname:maxLod must: be zero</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:addressModeU and pname:addressModeV must: each be either ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:anisotropyEnable must: be ename:VK_FALSE</usage>
-                <usage>If pname:unnormalizedCoordinates is ename:VK_TRUE, pname:compareEnable must: be ename:VK_FALSE</usage>
-                <usage>If any of pname:addressModeU, pname:addressModeV or pname:addressModeW are ename:VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, pname:borderColor must: be a valid elink:VkBorderColor value</usage>
-                <usage>If the +VK_KHR_sampler_mirror_clamp_to_edge+ extension is not enabled, pname:addressModeU, pname:addressModeV and pname:addressModeW must: not be ename:VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE</usage>
-                <usage>If pname:compareEnable is ename:VK_TRUE, pname:compareOp must: be a valid elink:VkCompareOp value</usage>
             </validity>
         </type>
         <type category="struct" name="VkCommandPoolCreateInfo">
@@ -1497,17 +1129,15 @@
             <member optional="true"><type>VkCommandPoolCreateFlags</type>   <name>flags</name></member>      <!-- Command pool creation flags -->
             <member><type>uint32_t</type>               <name>queueFamilyIndex</name></member>
             <validity>
-                <usage>pname:queueFamilyIndex must: be the index of a queue family available in the calling command's pname:device parameter</usage>
             </validity>
-         </type>
-         <type category="struct" name="VkCommandBufferAllocateInfo">
+        </type>
+        <type category="struct" name="VkCommandBufferAllocateInfo">
             <member values="VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO"><type>VkStructureType</type> <name>sType</name></member>
             <member>const <type>void</type>*            <name>pNext</name></member>                          <!-- Pointer to next structure -->
             <member><type>VkCommandPool</type>          <name>commandPool</name></member>
             <member><type>VkCommandBufferLevel</type>   <name>level</name></member>
             <member><type>uint32_t</type>               <name>commandBufferCount</name></member>
             <validity>
-                <usage>pname:commandBufferCount must: be greater than `0`</usage>
             </validity>
         </type>
         <type category="struct" name="VkCommandBufferInheritanceInfo">
@@ -1520,9 +1150,6 @@
             <member optional="true" noautovalidity="true"><type>VkQueryControlFlags</type>    <name>queryFlags</name></member>                     <!-- Query flags used by this secondary command buffer, if executed during an occlusion query -->
             <member optional="true" noautovalidity="true"><type>VkQueryPipelineStatisticFlags</type> <name>pipelineStatistics</name></member>      <!-- Pipeline statistics that may be counted for this secondary command buffer -->
             <validity>
-                <usage>If the &lt;&lt;features-features-inheritedQueries,inherited queries&gt;&gt; feature is not enabled, pname:occlusionQueryEnable must: be ename:VK_FALSE</usage>
-                <usage>If the &lt;&lt;features-features-inheritedQueries,inherited queries&gt;&gt; feature is enabled, pname:queryFlags must: be a valid combination of elink:VkQueryControlFlagBits values</usage>
-                <usage>If the &lt;&lt;features-features-pipelineStatisticsQuery,pipeline statistics queries&gt;&gt; feature is not enabled, pname:pipelineStatistics must: be code:0</usage>
             </validity>
         </type>
         <type category="struct" name="VkCommandBufferBeginInfo">
@@ -1531,9 +1158,6 @@
             <member optional="true"><type>VkCommandBufferUsageFlags</type>  <name>flags</name></member>                          <!-- Command buffer usage flags -->
             <member optional="true" noautovalidity="true">const <type>VkCommandBufferInheritanceInfo</type>*       <name>pInheritanceInfo</name></member>                          <!-- Pointer to inheritance info for secondary command buffers -->
             <validity>
-                <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:renderPass member of pname:pInheritanceInfo must: be a valid sname:VkRenderPass</usage>
-                <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:subpass member of pname:pInheritanceInfo must: be a valid subpass index within the pname:renderPass member of pname:pInheritanceInfo</usage>
-                <usage>If pname:flags contains ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, the pname:framebuffer member of pname:pInheritanceInfo must: be either dlink:VK_NULL_HANDLE, or a valid sname:VkFramebuffer that is compatible with the pname:renderPass member of pname:pInheritanceInfo</usage>
             </validity>
         </type>
         <type category="struct" name="VkRenderPassBeginInfo">
@@ -1545,7 +1169,6 @@
             <member optional="true"><type>uint32_t</type>               <name>clearValueCount</name></member>
             <member len="clearValueCount">const <type>VkClearValue</type>*    <name>pClearValues</name></member>
             <validity>
-                <usage>pname:clearValueCount must: be greater than the largest attachment index in pname:renderPass that specifies a pname:loadOp (or pname:stencilLoadOp, if the attachment has a depth/stencil format) of ename:VK_ATTACHMENT_LOAD_OP_CLEAR</usage>
             </validity>
         </type>
         <type category="union" name="VkClearColorValue" comment="// Union allowing specification of floating point, integer, or unsigned integer color data. Actual value selected is based on image/attachment being cleared.">
@@ -1556,6 +1179,8 @@
         <type category="struct" name="VkClearDepthStencilValue">
             <member><type>float</type>                  <name>depth</name></member>
             <member><type>uint32_t</type>               <name>stencil</name></member>
+            <validity>
+            </validity>
         </type>
         <type category="union" name="VkClearValue" comment="// Union allowing specification of color or depth and stencil values. Actual value selected is based on attachment being cleared.">
             <member><type>VkClearColorValue</type>      <name>color</name></member>
@@ -1566,8 +1191,6 @@
             <member><type>uint32_t</type>               <name>colorAttachment</name></member>
             <member><type>VkClearValue</type>           <name>clearValue</name></member>
             <validity>
-                <usage>If pname:aspectMask includes ename:VK_IMAGE_ASPECT_COLOR_BIT, it must: not include ename:VK_IMAGE_ASPECT_DEPTH_BIT or ename:VK_IMAGE_ASPECT_STENCIL_BIT</usage>
-                <usage>pname:aspectMask must: not include ename:VK_IMAGE_ASPECT_METADATA_BIT</usage>
             </validity>
         </type>
         <type category="struct" name="VkAttachmentDescription">
@@ -1581,14 +1204,12 @@
             <member><type>VkImageLayout</type>          <name>initialLayout</name></member>
             <member><type>VkImageLayout</type>          <name>finalLayout</name></member>
             <validity>
-                <usage>pname:finalLayout must: not be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED</usage>
             </validity>
         </type>
         <type category="struct" name="VkAttachmentReference">
             <member><type>uint32_t</type>               <name>attachment</name></member>
             <member><type>VkImageLayout</type>          <name>layout</name></member>
             <validity>
-                <usage>pname:layout must: not be ename:VK_IMAGE_LAYOUT_UNDEFINED or ename:VK_IMAGE_LAYOUT_PREINITIALIZED</usage>
             </validity>
         </type>
         <type category="struct" name="VkSubpassDescription">
@@ -1603,18 +1224,6 @@
             <member optional="true"><type>uint32_t</type>               <name>preserveAttachmentCount</name></member>
             <member len="preserveAttachmentCount">const <type>uint32_t</type>* <name>pPreserveAttachments</name></member>
             <validity>
-                <usage>pname:pipelineBindPoint must: be ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>pname:colorCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxColorAttachments</usage>
-                <usage>If the first use of an attachment in this render pass is as an input attachment, and the attachment is not also used as a color or depth/stencil attachment in the same subpass, then pname:loadOp must: not be ename:VK_ATTACHMENT_LOAD_OP_CLEAR</usage>
-                <usage>If pname:pResolveAttachments is not `NULL`, for each resolve attachment that does not have the value ename:VK_ATTACHMENT_UNUSED, the corresponding color attachment must: not have the value ename:VK_ATTACHMENT_UNUSED</usage>
-                <usage>If pname:pResolveAttachments is not `NULL`, the sample count of each element of pname:pColorAttachments must: be anything other than ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>Any given element of pname:pResolveAttachments must: have a sample count of ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>Any given element of pname:pResolveAttachments must: have the same elink:VkFormat as its corresponding color attachment</usage>
-                <usage>All attachments in pname:pColorAttachments and pname:pDepthStencilAttachment that are not ename:VK_ATTACHMENT_UNUSED must: have the same sample count</usage>
-                <usage>If any input attachments are ename:VK_ATTACHMENT_UNUSED, then any pipelines bound during the subpass must: not access those input attachments from the fragment shader</usage>
-                <usage>The pname:attachment member of any element of pname:pPreserveAttachments must: not be ename:VK_ATTACHMENT_UNUSED</usage>
-                <usage>Any given element of pname:pPreserveAttachments must: not also be an element of any other member of the subpass description</usage>
-                <usage>If any attachment is used as both an input attachment and a color or depth/stencil attachment, then each use must: use the same pname:layout</usage>
             </validity>
         </type>
         <type category="struct" name="VkSubpassDependency">
@@ -1626,14 +1235,6 @@
             <member optional="true"><type>VkAccessFlags</type>          <name>dstAccessMask</name></member>                  <!-- Memory accesses from the destination of the dependency to synchronize -->
             <member optional="true"><type>VkDependencyFlags</type>      <name>dependencyFlags</name></member>
             <validity>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>pname:srcSubpass must: be less than or equal to pname:dstSubpass, unless one of them is ename:VK_SUBPASS_EXTERNAL, to avoid cyclic dependencies and ensure a valid execution order</usage>
-                <usage>pname:srcSubpass and pname:dstSubpass must: not both be equal to ename:VK_SUBPASS_EXTERNAL</usage>
-                <usage>If pname:srcSubpass is equal to pname:dstSubpass, pname:srcStageMask and pname:dstStageMask must: only contain one of ename:VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, ename:VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, ename:VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, ename:VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, ename:VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, ename:VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, ename:VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, ename:VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, ename:VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, or ename:VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT</usage>
-                <usage>If pname:srcSubpass is equal to pname:dstSubpass, the highest bit value included in pname:srcStageMask must: be less than or equal to the lowest bit value in pname:dstStageMask</usage>
             </validity>
         </type>
         <type category="struct" name="VkRenderPassCreateInfo">
@@ -1647,10 +1248,6 @@
             <member optional="true"><type>uint32_t</type>       <name>dependencyCount</name></member>
             <member len="dependencyCount">const <type>VkSubpassDependency</type>* <name>pDependencies</name></member>
             <validity>
-                <usage>If any two subpasses operate on attachments with overlapping ranges of the same sname:VkDeviceMemory object, and at least one subpass writes to that area of sname:VkDeviceMemory, a subpass dependency must: be included (either directly or via some intermediate subpasses) between them</usage>
-                <usage>If the pname:attachment member of any element of pname:pInputAttachments, pname:pColorAttachments, pname:pResolveAttachments or pname:pDepthStencilAttachment, or the attachment indexed by any element of pname:pPreserveAttachments in any given element of pname:pSubpasses is bound to a range of a sname:VkDeviceMemory object that overlaps with any other attachment in any subpass (including the same subpass), the sname:VkAttachmentDescription structures describing them must: include ename:VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT in pname:flags</usage>
-                <usage>If the pname:attachment member of any element of pname:pInputAttachments, pname:pColorAttachments, pname:pResolveAttachments or pname:pDepthStencilAttachment, or any element of pname:pPreserveAttachments in any given element of pname:pSubpasses is not ename:VK_ATTACHMENT_UNUSED, it must: be less than pname:attachmentCount</usage>
-                <usage>The value of any element of the pname:pPreserveAttachments member in any given element of pname:pSubpasses must: not be ename:VK_ATTACHMENT_UNUSED</usage>
             </validity>
         </type>
         <type category="struct" name="VkEventCreateInfo">
@@ -1720,7 +1317,6 @@
             <member><type>VkBool32</type>               <name>variableMultisampleRate</name></member>           <!-- multisample rate must be the same for all pipelines in a subpass -->
             <member><type>VkBool32</type>               <name>inheritedQueries</name></member>                  <!-- Queries may be inherited from primary to secondary command buffers -->
             <validity>
-                <usage>If any member of this structure is ename:VK_FALSE, as returned by flink:vkGetPhysicalDeviceFeatures, then it must: be ename:VK_FALSE when passed as part of the sname:VkDeviceCreateInfo struct when creating a device</usage>
             </validity>
         </type>
         <type category="struct" name="VkPhysicalDeviceSparseProperties" returnedonly="true">
@@ -1792,31 +1388,24 @@
             <member><type>uint32_t</type>               <name>maxFragmentCombinedOutputResources</name></member><!-- max total number of storage buffers, storage images and output buffers -->
                 <!-- compute stage limits -->
             <member><type>uint32_t</type>               <name>maxComputeSharedMemorySize</name></member>        <!-- max total storage size of work group local storage (bytes) -->
-            <member><type>uint32_t</type>               <name>maxComputeWorkGroupCount</name>[3]</member>       <!-- max num of compute work groups that may be dispatched
-                                                                                                                     by a single command (x,y,z) -->
+            <member><type>uint32_t</type>               <name>maxComputeWorkGroupCount</name>[3]</member>       <!-- max num of compute work groups that may be dispatched by a single command (x,y,z) -->
             <member><type>uint32_t</type>               <name>maxComputeWorkGroupInvocations</name></member>    <!-- max total compute invocations in a single local work group -->
             <member><type>uint32_t</type>               <name>maxComputeWorkGroupSize</name>[3]</member>        <!-- max local size of a compute work group (x,y,z) -->
-
             <member><type>uint32_t</type>               <name>subPixelPrecisionBits</name></member>             <!-- number bits of subpixel precision in screen x and y-->
             <member><type>uint32_t</type>               <name>subTexelPrecisionBits</name></member>             <!-- number bits of precision for selecting texel weights-->
             <member><type>uint32_t</type>               <name>mipmapPrecisionBits</name></member>               <!-- number bits of precision for selecting mipmap weights -->
-
             <member><type>uint32_t</type>               <name>maxDrawIndexedIndexValue</name></member>          <!-- max index value for indexed draw calls (for 32-bit indices) -->
             <member><type>uint32_t</type>               <name>maxDrawIndirectCount</name></member>              <!-- max draw count for indirect draw calls -->
-
             <member><type>float</type>                  <name>maxSamplerLodBias</name></member>                 <!-- max absolute sampler level of detail bias -->
             <member><type>float</type>                  <name>maxSamplerAnisotropy</name></member>              <!-- max degree of sampler anisotropy -->
-
             <member><type>uint32_t</type>               <name>maxViewports</name></member>                      <!-- max number of active viewports -->
             <member><type>uint32_t</type>               <name>maxViewportDimensions</name>[2]</member>          <!-- max viewport dimensions (x,y) -->
             <member><type>float</type>                  <name>viewportBoundsRange</name>[2]</member>            <!-- viewport bounds range (min,max) -->
             <member><type>uint32_t</type>               <name>viewportSubPixelBits</name></member>              <!-- number bits of subpixel precision for viewport -->
-
             <member><type>size_t</type>                 <name>minMemoryMapAlignment</name></member>             <!-- min required alignment of pointers returned by MapMemory (bytes) -->
             <member><type>VkDeviceSize</type>           <name>minTexelBufferOffsetAlignment</name></member>     <!-- min required alignment for texel buffer offsets (bytes)  -->
             <member><type>VkDeviceSize</type>           <name>minUniformBufferOffsetAlignment</name></member>   <!-- min required alignment for uniform buffer sizes and offsets (bytes) -->
             <member><type>VkDeviceSize</type>           <name>minStorageBufferOffsetAlignment</name></member>   <!-- min required alignment for storage buffer offsets (bytes) -->
-
             <member><type>int32_t</type>                <name>minTexelOffset</name></member>                    <!-- min texel offset for OpTextureSampleOffset -->
             <member><type>uint32_t</type>               <name>maxTexelOffset</name></member>                    <!-- max texel offset for OpTextureSampleOffset -->
             <member><type>int32_t</type>                <name>minTexelGatherOffset</name></member>              <!-- min texel offset for OpTextureGatherOffset -->
@@ -1824,7 +1413,6 @@
             <member><type>float</type>                  <name>minInterpolationOffset</name></member>            <!-- furthest negative offset for interpolateAtOffset -->
             <member><type>float</type>                  <name>maxInterpolationOffset</name></member>            <!-- furthest positive offset for interpolateAtOffset -->
             <member><type>uint32_t</type>               <name>subPixelInterpolationOffsetBits</name></member>   <!-- number of subpixel bits for interpolateAtOffset -->
-
             <member><type>uint32_t</type>               <name>maxFramebufferWidth</name></member>               <!-- max width for a framebuffer -->
             <member><type>uint32_t</type>               <name>maxFramebufferHeight</name></member>              <!-- max height for a framebuffer -->
             <member><type>uint32_t</type>               <name>maxFramebufferLayers</name></member>              <!-- max layer count for a layered framebuffer -->
@@ -1833,23 +1421,18 @@
             <member optional="true"><type>VkSampleCountFlags</type>     <name>framebufferStencilSampleCounts</name></member>    <!-- supported stencil sample counts for a framebuffer -->
             <member optional="true"><type>VkSampleCountFlags</type>     <name>framebufferNoAttachmentsSampleCounts</name></member> <!-- supported sample counts for a framebuffer with no attachments -->
             <member><type>uint32_t</type>               <name>maxColorAttachments</name></member>               <!-- max number of color attachments per subpass -->
-
             <member optional="true"><type>VkSampleCountFlags</type>     <name>sampledImageColorSampleCounts</name></member>     <!-- supported color sample counts for a non-integer sampled image -->
             <member optional="true"><type>VkSampleCountFlags</type>     <name>sampledImageIntegerSampleCounts</name></member>   <!-- supported sample counts for an integer image -->
             <member optional="true"><type>VkSampleCountFlags</type>     <name>sampledImageDepthSampleCounts</name></member>     <!-- supported depth sample counts for a sampled image -->
             <member optional="true"><type>VkSampleCountFlags</type>     <name>sampledImageStencilSampleCounts</name></member>   <!-- supported stencil sample counts for a sampled image -->
             <member optional="true"><type>VkSampleCountFlags</type>     <name>storageImageSampleCounts</name></member>          <!-- supported sample counts for a storage image -->
             <member><type>uint32_t</type>               <name>maxSampleMaskWords</name></member>                <!-- max number of sample mask words -->
-
             <member><type>VkBool32</type>               <name>timestampComputeAndGraphics</name></member>       <!-- timestamps on graphics and compute queues -->
             <member><type>float</type>                  <name>timestampPeriod</name></member>                   <!-- number of nanoseconds it takes for timestamp query value to increment by 1 -->
-
             <member><type>uint32_t</type>               <name>maxClipDistances</name></member>                  <!-- max number of clip distances -->
             <member><type>uint32_t</type>               <name>maxCullDistances</name></member>                  <!-- max number of cull distances -->
             <member><type>uint32_t</type>               <name>maxCombinedClipAndCullDistances</name></member>   <!-- max combined number of user clipping -->
-
             <member><type>uint32_t</type>               <name>discreteQueuePriorities</name></member>           <!-- distinct queue priorities available  -->
-
             <member><type>float</type>                  <name>pointSizeRange</name>[2]</member>                 <!-- range (min,max) of supported point sizes -->
             <member><type>float</type>                  <name>lineWidthRange</name>[2]</member>                 <!-- range (min,max) of supported line widths -->
             <member><type>float</type>                  <name>pointSizeGranularity</name></member>              <!-- granularity of supported point sizes -->
@@ -1873,8 +1456,6 @@
             <member><type>uint32_t</type>               <name>queryCount</name></member>
             <member optional="true" noautovalidity="true"><type>VkQueryPipelineStatisticFlags</type> <name>pipelineStatistics</name></member>      <!-- Optional -->
             <validity>
-                <usage>If the &lt;&lt;features-features-pipelineStatisticsQuery,pipeline statistics queries&gt;&gt; feature is not enabled, pname:queryType must: not be ename:VK_QUERY_TYPE_PIPELINE_STATISTICS</usage>
-                <usage>If pname:queryType is ename:VK_QUERY_TYPE_PIPELINE_STATISTICS, pname:pipelineStatistics must: be a valid combination of elink:VkQueryPipelineStatisticFlagBits values</usage>
             </validity>
         </type>
         <type category="struct" name="VkFramebufferCreateInfo">
@@ -1888,18 +1469,6 @@
             <member><type>uint32_t</type>               <name>height</name></member>
             <member><type>uint32_t</type>               <name>layers</name></member>
             <validity>
-                <usage>pname:attachmentCount must: be equal to the attachment count specified in pname:renderPass</usage>
-                <usage>Any given element of pname:pAttachments that is used as a color attachment or resolve attachment by pname:renderPass must: have been created with a pname:usage value including ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT</usage>
-                <usage>Any given element of pname:pAttachments that is used as a depth/stencil attachment by pname:renderPass must: have been created with a pname:usage value including ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT</usage>
-                <usage>Any given element of pname:pAttachments that is used as an input attachment by pname:renderPass must: have been created with a pname:usage value including ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT</usage>
-                <usage>Any given element of pname:pAttachments must: have been created with an elink:VkFormat value that matches the elink:VkFormat specified by the corresponding sname:VkAttachmentDescription in pname:renderPass</usage>
-                <usage>Any given element of pname:pAttachments must: have been created with a pname:samples value that matches the pname:samples value specified by the corresponding sname:VkAttachmentDescription in pname:renderPass</usage>
-                <usage>Any given element of pname:pAttachments must: have dimensions at least as large as the corresponding framebuffer dimension</usage>
-                <usage>Any given element of pname:pAttachments must: only specify a single mip level</usage>
-                <usage>Any given element of pname:pAttachments must: have been created with the identity swizzle</usage>
-                <usage>pname:width must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferWidth</usage>
-                <usage>pname:height must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferHeight</usage>
-                <usage>pname:layers must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxFramebufferLayers</usage>
             </validity>
         </type>
         <type category="struct" name="VkDrawIndirectCommand">
@@ -1908,8 +1477,6 @@
             <member><type>uint32_t</type>               <name>firstVertex</name></member>
             <member><type>uint32_t</type>               <name>firstInstance</name></member>
             <validity>
-                <usage>For a given vertex buffer binding, any attribute data fetched must: be entirely contained within the corresponding vertex buffer binding, as described in &lt;&lt;fxvertex-input&gt;&gt;</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, pname:firstInstance must: be code:0</usage>
             </validity>
         </type>
         <type category="struct" name="VkDrawIndexedIndirectCommand">
@@ -1919,9 +1486,6 @@
             <member><type>int32_t</type>                <name>vertexOffset</name></member>
             <member><type>uint32_t</type>               <name>firstInstance</name></member>
             <validity>
-                <usage>For a given vertex buffer binding, any attribute data fetched must: be entirely contained within the corresponding vertex buffer binding, as described in &lt;&lt;fxvertex-input&gt;&gt;</usage>
-                <usage>(pname:indexSize * (pname:firstIndex + pname:indexCount) + pname:offset) must: be less than or equal to the size of the currently bound index buffer, with pname:indexSize being based on the type specified by pname:indexType, where the index buffer, pname:indexType, and pname:offset are specified via fname:vkCmdBindIndexBuffer</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, pname:firstInstance must: be code:0</usage>
             </validity>
         </type>
         <type category="struct" name="VkDispatchIndirectCommand">
@@ -1929,9 +1493,6 @@
             <member><type>uint32_t</type>               <name>y</name></member>
             <member><type>uint32_t</type>               <name>z</name></member>
             <validity>
-                <usage>pname:x must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0]</usage>
-                <usage>pname:y must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1]</usage>
-                <usage>pname:z must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2]</usage>
             </validity>
         </type>
         <type category="struct" name="VkSubmitInfo">
@@ -1945,22 +1506,10 @@
             <member optional="true"><type>uint32_t</type>       <name>signalSemaphoreCount</name></member>
             <member len="signalSemaphoreCount">const <type>VkSemaphore</type>*     <name>pSignalSemaphores</name></member>
             <validity>
-                <usage>Any given element of pname:pSignalSemaphores must: currently be unsignaled</usage>
-                <usage>Any given element of pname:pCommandBuffers must: either have been recorded with the ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device</usage>
-                <usage>Any given element of pname:pCommandBuffers must: be in the executable state</usage>
-                <usage>If any given element of pname:pCommandBuffers contains commands that execute secondary command buffers, those secondary command buffers must: have been recorded with the ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT, or not currently be executing on the device</usage>
-                <usage>If any given element of pname:pCommandBuffers was recorded with ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, it must: not have been previously submitted without re-recording that command buffer</usage>
-                <usage>If any given element of pname:pCommandBuffers contains commands that execute secondary command buffers recorded with ename:VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, each such secondary command buffer must: not have been previously submitted without re-recording that command buffer</usage>
-                <usage>Any given element of pname:pCommandBuffers must: not contain commands that execute a secondary command buffer, if that secondary command buffer has been recorded in another primary command buffer after it was recorded into this sname:VkCommandBuffer</usage>
-                <usage>Any given element of pname:pCommandBuffers must: have been allocated from a sname:VkCommandPool that was created for the same queue family that the calling command's pname:queue belongs to</usage>
-                <usage>Any given element of pname:pCommandBuffers must: not have been allocated with ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY</usage>
-                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that will not be consumed by any other wait on that semaphore</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, any given element of pname:pWaitDstStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, any given element of pname:pWaitDstStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
             </validity>
         </type>
         <!-- WSI extensions -->
-        <type category="struct" name="VkDisplayPropertiesKHR">
+        <type category="struct" name="VkDisplayPropertiesKHR" returnedonly="true">
             <member><type>VkDisplayKHR</type>                     <name>display</name></member>                  <!-- Handle of the display object -->
             <member len="null-terminated">const <type>char</type>*                      <name>displayName</name></member>              <!-- Name of the display -->
             <member><type>VkExtent2D</type>                       <name>physicalDimensions</name></member>       <!-- In millimeters? -->
@@ -1969,7 +1518,7 @@
             <member><type>VkBool32</type>                         <name>planeReorderPossible</name></member>     <!-- VK_TRUE if the overlay plane's z-order can be changed on this display. -->
             <member><type>VkBool32</type>                         <name>persistentContent</name></member>        <!-- VK_TRUE if this is a "smart" display that supports self-refresh/internal buffering. -->
         </type>
-        <type category="struct" name="VkDisplayPlanePropertiesKHR">
+        <type category="struct" name="VkDisplayPlanePropertiesKHR" returnedonly="true">
             <member><type>VkDisplayKHR</type>                     <name>currentDisplay</name></member>           <!-- Display the plane is currently associated with.  Will be VK_NULL_HANDLE if the plane is not in use. -->
             <member><type>uint32_t</type>                         <name>currentStackIndex</name></member>        <!-- Current z-order of the plane. -->
         </type>
@@ -1977,7 +1526,7 @@
             <member><type>VkExtent2D</type>                       <name>visibleRegion</name></member>            <!-- Visible scanout region. -->
             <member><type>uint32_t</type>                         <name>refreshRate</name></member>              <!-- Number of times per second the display is updated. -->
         </type>
-        <type category="struct" name="VkDisplayModePropertiesKHR">
+        <type category="struct" name="VkDisplayModePropertiesKHR" returnedonly="true">
             <member><type>VkDisplayModeKHR</type>                 <name>displayMode</name></member>              <!-- Handle of this display mode. -->
             <member><type>VkDisplayModeParametersKHR</type>       <name>parameters</name></member>               <!-- The parameters this mode uses. -->
         </type>
@@ -1987,11 +1536,9 @@
             <member optional="true"><type>VkDisplayModeCreateFlagsKHR</type>      <name>flags</name></member>                    <!-- Reserved -->
             <member><type>VkDisplayModeParametersKHR</type>       <name>parameters</name></member>               <!-- The parameters this mode uses. -->
             <validity>
-                <usage>The pname:width and pname:height members of the pname:visibleRegion member of pname:parameters must: be greater than `0`</usage>
-                <usage>The pname:refreshRate member of pname:parameters must: be greater than `0`</usage>
             </validity>
         </type>
-        <type category="struct" name="VkDisplayPlaneCapabilitiesKHR">
+        <type category="struct" name="VkDisplayPlaneCapabilitiesKHR" returnedonly="true">
             <member optional="true"><type>VkDisplayPlaneAlphaFlagsKHR</type>      <name>supportedAlpha</name></member>           <!-- Types of alpha blending supported, if any. -->
             <member><type>VkOffset2D</type>                       <name>minSrcPosition</name></member>           <!-- Does the plane have any position and extent restrictions? -->
             <member><type>VkOffset2D</type>                       <name>maxSrcPosition</name></member>
@@ -2014,11 +1561,6 @@
             <member><type>VkDisplayPlaneAlphaFlagBitsKHR</type>   <name>alphaMode</name></member>                <!-- What type of alpha blending to use.  Must be a bit from vkGetDisplayPlanePropertiesKHR::supportedAlpha. -->
             <member><type>VkExtent2D</type>                       <name>imageExtent</name></member>              <!-- size of the images to use with this surface -->
             <validity>
-                <usage>pname:planeIndex must: be less than the number of display planes supported by the device as determined by calling fname:vkGetPhysicalDeviceDisplayPlanePropertiesKHR</usage>
-                <usage>If the pname:planeReorderPossible member of the sname:VkDisplayPropertiesKHR structure returned by fname:vkGetPhysicalDeviceDisplayPropertiesKHR for the display corresponding to pname:displayMode is ename:VK_TRUE then pname:planeStackIndex must: be less than the number of display planes supported by the device as determined by calling fname:vkGetPhysicalDeviceDisplayPlanePropertiesKHR; otherwise pname:planeStackIndex must: equal the pname:currentStackIndex member of sname:VkDisplayPlanePropertiesKHR returned by fname:vkGetPhysicalDeviceDisplayPlanePropertiesKHR for the display plane corresponding to pname:displayMode</usage>
-                <usage>If pname:alphaMode is ename:VK_DISPLAY_PLANE_ALPHA_GLOBAL_BIT_KHR then pname:globalAlpha must: be between `0` and `1`, inclusive</usage>
-                <usage>pname:alphaMode must: be `0` or one of the bits present in the pname:supportedAlpha member of sname:VkDisplayPlaneCapabilitiesKHR returned by fname:vkGetDisplayPlaneCapabilitiesKHR for the display plane corresponding to pname:displayMode</usage>
-                <usage>The pname:width and pname:height members of pname:imageExtent must: be less than the pname:maxImageDimensions2D member of sname:VkPhysicalDeviceLimits</usage>
             </validity>
         </type>
         <type category="struct" name="VkDisplayPresentInfoKHR">
@@ -2028,12 +1570,9 @@
             <member><type>VkRect2D</type>                         <name>dstRect</name></member>                  <!-- Rectangle within the current display mode's visible region to display srcRectangle in. -->
             <member><type>VkBool32</type>                         <name>persistent</name></member>               <!-- For smart displays, use buffered mode.  If the display properties member "persistentMode" is VK_FALSE, this member must always be VK_FALSE. -->
             <validity>
-                <usage>pname:srcRect must: specify a rectangular region that is a subset of the image being presented</usage>
-                <usage>pname:dstRect must: specify a rectangular region that is a subset of the pname:visibleRegion parameter of the display mode the swapchain being presented uses</usage>
-                <usage>If the pname:persistentContent member of the sname:VkDisplayPropertiesKHR structure returned by fname:vkGetPhysicalDeviceDisplayPropertiesKHR for the display the present operation targets then pname:persistent must: be ename:VK_FALSE</usage>
             </validity>
         </type>
-        <type category="struct" name="VkSurfaceCapabilitiesKHR">
+        <type category="struct" name="VkSurfaceCapabilitiesKHR" returnedonly="true">
             <member><type>uint32_t</type>                         <name>minImageCount</name></member>            <!-- Supported minimum number of images for the surface -->
             <member><type>uint32_t</type>                         <name>maxImageCount</name></member>            <!-- Supported maximum number of images for the surface, 0 for unlimited -->
             <member><type>VkExtent2D</type>                       <name>currentExtent</name></member>            <!-- Current image width and height for the surface, (0, 0) if undefined -->
@@ -2051,7 +1590,6 @@
             <member optional="true"><type>VkAndroidSurfaceCreateFlagsKHR</type>   <name>flags</name></member>    <!-- Reserved -->
             <member><type>ANativeWindow</type>*                   <name>window</name></member>
             <validity>
-                <usage>pname:window must: not be in a connected state</usage>
             </validity>
         </type>
         <type category="struct" name="VkMirSurfaceCreateInfoKHR">
@@ -2089,7 +1627,7 @@
             <member><type>xcb_connection_t</type>*                <name>connection</name></member>
             <member><type>xcb_window_t</type>                     <name>window</name></member>
         </type>
-        <type category="struct" name="VkSurfaceFormatKHR">
+        <type category="struct" name="VkSurfaceFormatKHR" returnedonly="true">
             <member><type>VkFormat</type>                         <name>format</name></member>                   <!-- Supported pair of rendering format -->
             <member><type>VkColorSpaceKHR</type>                  <name>colorSpace</name></member>               <!-- and color space for the surface -->
         </type>
@@ -2113,19 +1651,6 @@
             <member><type>VkBool32</type>                         <name>clipped</name></member>                  <!-- Specifies whether presentable images may be affected by window clip regions -->
             <member optional="true"><type>VkSwapchainKHR</type>   <name>oldSwapchain</name></member>             <!-- Existing swap chain to replace, if any -->
             <validity>
-                <usage>pname:surface must: be a surface that is supported by the device as determined using fname:vkGetPhysicalDeviceSurfaceSupportKHR</usage>
-                <usage>The native window referred to by pname:surface must: not already be associated with a swapchain other than pname:oldSwapchain, or with a non-Vulkan graphics API surface</usage>
-                <usage>pname:minImageCount must: be greater than or equal to the value returned in the pname:minImageCount member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>pname:minImageCount must: be less than or equal to the value returned in the pname:maxImageCount member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface if the returned pname:maxImageCount is not zero</usage>
-                <usage>pname:imageFormat and pname:imageColorspace must: match the pname:format and pname:colorSpace members, respectively, of one of the sname:VkSurfaceFormatKHR structures returned by fname:vkGetPhysicalDeviceSurfaceFormatsKHR for the surface</usage>
-                <usage>pname:imageExtent must: be between pname:minImageExtent and pname:maxImageExtent, inclusive, where pname:minImageExtent and pname:maxImageExtent are members of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>pname:imageArrayLayers must: be greater than `0` and less than or equal to the pname:maxImageArrayLayers member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>pname:imageUsage must: be a subset of the supported usage flags present in the pname:supportedUsageFlags member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:pQueueFamilyIndices must: be a pointer to an array of pname:queueFamilyIndexCount basetype:uint32_t values</usage>
-                <usage>If pname:imageSharingMode is ename:VK_SHARING_MODE_CONCURRENT, pname:queueFamilyIndexCount must: be greater than `1`</usage>
-                <usage>pname:preTransform must: be one of the bits present in the pname:supportedTransforms member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>pname:compositeAlpha must: be one of the bits present in the pname:supportedCompositeAlpha member of the sname:VkSurfaceCapabilitiesKHR structure returned by fname:vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface</usage>
-                <usage>pname:presentMode must: be one of the ename:VkPresentModeKHR values returned by fname:vkGetPhysicalDeviceSurfacePresentModesKHR for the surface</usage>
             </validity>
         </type>
         <type category="struct" name="VkPresentInfoKHR">
@@ -2138,8 +1663,6 @@
             <member len="swapchainCount">const <type>uint32_t</type>* <name>pImageIndices</name></member>        <!-- Indices of which swapchain images to present -->
             <member optional="true" len="swapchainCount"><type>VkResult</type>* <name>pResults</name></member>   <!-- Optional (i.e. if non-NULL) VkResult for each swapchain -->
             <validity>
-                <usage>Any given element of pname:pImageIndices must: be the index of a presentable image acquired from the swapchain specified by the corresponding element of the pname:pSwapchains array</usage>
-                <usage>Any given element of sname:VkSemaphore in pname:pWaitSemaphores must: refer to a prior signal of that sname:VkSemaphore that will not be consumed by any other wait on that semaphore</usage>
             </validity>
         </type>
         <type category="struct" name="VkDebugReportCallbackCreateInfoEXT">
@@ -2149,6 +1672,12 @@
             <member><type>PFN_vkDebugReportCallbackEXT</type>     <name>pfnCallback</name></member>              <!-- Function pointer of a callback function-->
             <member optional="true"><type>void</type>*            <name>pUserData</name></member>                <!-- User data provided to callback function -->
         </type>
+        <type category="struct" name="VkValidationFlagsEXT">
+            <member><type>VkStructureType</type>                  <name>sType</name></member>                    <!-- Must be VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT -->
+            <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
+            <member><type>uint32_t</type>                         <name>disabledValidationCheckCount</name></member>   <!-- Number of validation checks to disable -->
+            <member len="disabledValidationCheckCount"><type>VkValidationCheckEXT</type>* <name>pDisabledValidationChecks</name></member>   <!-- Validation checks to disable -->
+        </type>
         <type category="struct" name="VkPipelineRasterizationStateRasterizationOrderAMD">
             <member values="VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD"><type>VkStructureType</type> <name>sType</name></member>
             <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
@@ -2181,7 +1710,6 @@
             <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
             <member><type>VkBool32</type>                         <name>dedicatedAllocation</name></member>      <!-- Whether this image uses a dedicated allocation -->
             <validity>
-                <usage>If pname:dedicatedAllocation is ename:VK_TRUE, sname:VkImageCreateInfo::pname:flags must: not include ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT, ename:VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, or ename:VK_IMAGE_CREATE_SPARSE_ALIASED_BIT</usage>
             </validity>
         </type>
         <type category="struct" name="VkDedicatedAllocationBufferCreateInfoNV">
@@ -2189,7 +1717,6 @@
             <member>const <type>void</type>*                      <name>pNext</name></member>                    <!-- Pointer to next structure -->
             <member><type>VkBool32</type>                         <name>dedicatedAllocation</name></member>      <!-- Whether this buffer uses a dedicated allocation -->
             <validity>
-                <usage>If pname:dedicatedAllocation is ename:VK_TRUE, sname:VkBufferCreateInfo::pname:flags must: not include ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT, ename:VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, or ename:VK_BUFFER_CREATE_SPARSE_ALIASED_BIT</usage>
             </validity>
         </type>
         <type category="struct" name="VkDedicatedAllocationMemoryAllocateInfoNV">
@@ -2198,11 +1725,6 @@
             <member optional="true"><type>VkImage</type>          <name>image</name></member>                    <!-- Image that this allocation will be bound to -->
             <member optional="true"><type>VkBuffer</type>         <name>buffer</name></member>                   <!-- Buffer that this allocation will be bound to -->
             <validity>
-                <usage>At least one of pname:image and pname:buffer must: be sname:VK_NULL_HANDLE</usage>
-                <usage>If pname:image is not sname:VK_NULL_HANDLE, the image must: have been created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE</usage>
-                <usage>If pname:buffer is not sname:VK_NULL_HANDLE, the buffer must: have been created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE</usage>
-                <usage>If pname:image is not sname:VK_NULL_HANDLE, sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the sname:VkMemoryRequirements::pname:size of the image</usage>
-                <usage>If pname:buffer is not sname:VK_NULL_HANDLE, sname:VkMemoryAllocateInfo::pname:allocationSize must: equal the sname:VkMemoryRequirements::pname:size of the buffer</usage>
             </validity>
         </type>
         <type category="struct" name="VkExternalImageFormatPropertiesNV">
@@ -2236,13 +1758,13 @@
         <type category="struct" name="VkWin32KeyedMutexAcquireReleaseInfoNV">
             <member values="VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV"><type>VkStructureType</type> <name>sType</name></member>
             <member>const <type>void</type>*                      <name>pNext</name></member>
-            <member><type>uint32_t</type>                         <name>acquireCount</name></member>
-            <member>const <type>VkDeviceMemory</type>*            <name>pAcquireSyncs</name></member>
-            <member>const <type>uint64_t</type>*                  <name>pAcquireKeys</name></member>
-            <member>const <type>uint32_t</type>*                  <name>pAcquireTimeoutMilliseconds</name></member>
-            <member><type>uint32_t</type>                         <name>releaseCount</name></member>
-            <member>const <type>VkDeviceMemory</type>*            <name>pReleaseSyncs</name></member>
-            <member>const <type>uint64_t</type>*                  <name>pReleaseKeys</name></member>
+            <member optional="true"><type>uint32_t</type>                         <name>acquireCount</name></member>
+            <member len="acquireCount">const <type>VkDeviceMemory</type>*            <name>pAcquireSyncs</name></member>
+            <member len="acquireCount">const <type>uint64_t</type>*                  <name>pAcquireKeys</name></member>
+            <member len="acquireCount">const <type>uint32_t</type>*                  <name>pAcquireTimeoutMilliseconds</name></member>
+            <member optional="true"><type>uint32_t</type>                         <name>releaseCount</name></member>
+            <member len="releaseCount">const <type>VkDeviceMemory</type>*            <name>pReleaseSyncs</name></member>
+            <member len="releaseCount">const <type>uint64_t</type>*                  <name>pReleaseKeys</name></member>
         </type>
     </types>
 
@@ -2356,7 +1878,7 @@
         <enum value="1"     name="VK_PIPELINE_BIND_POINT_COMPUTE"/>
     </enums>
     <enums name="VkPipelineCacheHeaderVersion" type="enum">
-       <enum value="1"     name="VK_PIPELINE_CACHE_HEADER_VERSION_ONE"/>
+        <enum value="1"     name="VK_PIPELINE_CACHE_HEADER_VERSION_ONE"/>
     </enums>
     <enums name="VkPrimitiveTopology" type="enum">
         <enum value="0"     name="VK_PRIMITIVE_TOPOLOGY_POINT_LIST"/>
@@ -3064,6 +2586,10 @@
         <enum bitpos="1" name="VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_NV"/>
         <enum bitpos="2" name="VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_NV"/>
     </enums>
+    <enums name="VkValidationCheckEXT" type="enum">
+        <enum value="0" name="VK_VALIDATION_CHECK_ALL_EXT"/>
+        <!-- Placeholder for validation enums to be defined for VK_EXT_Validation_flags extension -->
+    </enums>
 
     <!-- SECTION: Vulkan command definitions -->
     <commands>
@@ -3078,9 +2604,6 @@
             <param optional="true" externsync="true"><type>VkInstance</type> <name>instance</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All child objects created using pname:instance must: have been destroyed prior to destroying pname:instance</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:instance was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:instance was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INITIALIZATION_FAILED">
@@ -3148,9 +2671,6 @@
             <param optional="true" externsync="true"><type>VkDevice</type> <name>device</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All child objects created on pname:device must: have been destroyed prior to destroying pname:device</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:device was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:device was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3164,7 +2684,6 @@
             <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
             <param optional="true" len="pPropertyCount"><type>VkExtensionProperties</type>* <name>pProperties</name></param>
             <validity>
-                <usage>If pname:pLayerName is not `NULL`, it must: be the name of a layer returned by flink:vkEnumerateInstanceLayerProperties</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3180,7 +2699,6 @@
             <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
             <param optional="true" len="pPropertyCount"><type>VkExtensionProperties</type>* <name>pProperties</name></param>
             <validity>
-                <usage>If pname:pLayerName is not `NULL`, it must: be the name of a layer returned by flink:vkEnumerateDeviceLayerProperties</usage>
             </validity>
         </command>
         <command>
@@ -3190,8 +2708,6 @@
             <param><type>uint32_t</type> <name>queueIndex</name></param>
             <param><type>VkQueue</type>* <name>pQueue</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be one of the queue family indices specified when pname:device was created, via the sname:VkDeviceQueueCreateInfo structure</usage>
-                <usage>pname:queueIndex must: be less than the number of queues created for the specified queue family index when pname:device was created, via the pname:queueCount member of the sname:VkDeviceQueueCreateInfo structure</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3201,8 +2717,6 @@
             <param len="submitCount" externsync="pSubmits[].pWaitSemaphores[],pSubmits[].pSignalSemaphores[]">const <type>VkSubmitInfo</type>* <name>pSubmits</name></param>
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <validity>
-                <usage>If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: be unsignaled</usage>
-                <usage>If pname:fence is not dlink:VK_NULL_HANDLE, pname:fence must: not be associated with any other queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3223,7 +2737,6 @@
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <param><type>VkDeviceMemory</type>* <name>pMemory</name></param>
             <validity>
-                <usage>The number of currently valid memory objects, allocated from pname:device, must: be less than sname:VkPhysicalDeviceLimits::pname:maxMemoryAllocationCount</usage>
             </validity>
         </command>
         <command>
@@ -3232,7 +2745,6 @@
             <param optional="true" externsync="true"><type>VkDeviceMemory</type> <name>memory</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:memory (via images or buffers) must: have completed execution</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_MEMORY_MAP_FAILED">
@@ -3244,11 +2756,6 @@
             <param optional="true"><type>VkMemoryMapFlags</type> <name>flags</name></param>
             <param><type>void</type>** <name>ppData</name></param>
             <validity>
-                <usage>pname:memory must: not currently be mapped</usage>
-                <usage>pname:offset must: be less than the size of pname:memory</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be greater than `0`</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be less than or equal to the size of the pname:memory minus pname:offset</usage>
-                <usage>pname:memory must: have been created with a memory type that reports ename:VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT</usage>
             </validity>
         </command>
         <command>
@@ -3256,7 +2763,6 @@
             <param><type>VkDevice</type> <name>device</name></param>
             <param externsync="true"><type>VkDeviceMemory</type> <name>memory</name></param>
             <validity>
-                <usage>pname:memory must: currently be mapped</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3277,7 +2783,6 @@
             <param><type>VkDeviceMemory</type> <name>memory</name></param>
             <param><type>VkDeviceSize</type>* <name>pCommittedMemoryInBytes</name></param>
             <validity>
-                <usage>pname:memory must: have been created with a memory type that reports ename:VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT</usage>
             </validity>
         </command>
         <command>
@@ -3293,15 +2798,6 @@
             <param><type>VkDeviceMemory</type> <name>memory</name></param>
             <param><type>VkDeviceSize</type> <name>memoryOffset</name></param>
             <validity>
-                <usage>pname:buffer must: not already be backed by a memory object</usage>
-                <usage>pname:buffer must: not have been created with any sparse memory binding flags</usage>
-                <usage>pname:memoryOffset must: be less than the size of pname:memory</usage>
-                <usage>If pname:buffer was created with the ename:VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT or ename:VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, pname:memoryOffset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minTexelBufferOffsetAlignment</usage>
-                <usage>If pname:buffer was created with the ename:VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, pname:memoryOffset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minUniformBufferOffsetAlignment</usage>
-                <usage>If pname:buffer was created with the ename:VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, pname:memoryOffset must: be a multiple of sname:VkPhysicalDeviceLimits::pname:minStorageBufferOffsetAlignment</usage>
-                <usage>pname:memory must: have been allocated using one of the memory types allowed in the pname:memoryTypeBits member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer</usage>
-                <usage>pname:memoryOffset must: be an integer multiple of the pname:alignment member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer</usage>
-                <usage>The pname:size member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetBufferMemoryRequirements with pname:buffer must: be less than or equal to the size of pname:memory minus pname:memoryOffset</usage>
             </validity>
         </command>
         <command>
@@ -3317,12 +2813,6 @@
             <param><type>VkDeviceMemory</type> <name>memory</name></param>
             <param><type>VkDeviceSize</type> <name>memoryOffset</name></param>
             <validity>
-                <usage>pname:image must: not already be backed by a memory object</usage>
-                <usage>pname:image must: not have been created with any sparse memory binding flags</usage>
-                <usage>pname:memoryOffset must: be less than the size of pname:memory</usage>
-                <usage>pname:memory must: have been allocated using one of the memory types allowed in the pname:memoryTypeBits member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetImageMemoryRequirements with pname:image</usage>
-                <usage>pname:memoryOffset must: be an integer multiple of the pname:alignment member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetImageMemoryRequirements with pname:image</usage>
-                <usage>The pname:size member of the sname:VkMemoryRequirements structure returned from a call to fname:vkGetImageMemoryRequirements with pname:image must: be less than or equal to the size of pname:memory minus pname:memoryOffset</usage>
             </validity>
         </command>
         <command>
@@ -3343,7 +2833,6 @@
             <param optional="false,true"><type>uint32_t</type>* <name>pPropertyCount</name></param>
             <param optional="true" len="pPropertyCount"><type>VkSparseImageFormatProperties</type>* <name>pProperties</name></param>
             <validity>
-                <usage>pname:samples must: be a bit value that is set in sname:VkImageFormatProperties::pname:sampleCounts returned by fname:vkGetPhysicalDeviceImageFormatProperties with pname:format, pname:type, pname:tiling, and pname:usage equal to those in this command and pname:flags equal to the value that is set in sname::VkImageCreateInfo::pname::flags when the image is created</usage>
             </validity>
         </command>
         <command queues="sparse_binding" successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3353,8 +2842,6 @@
             <param len="bindInfoCount" externsync="pBindInfo[].pWaitSemaphores[],pBindInfo[].pSignalSemaphores[],pBindInfo[].pBufferBinds[].buffer,pBindInfo[].pImageOpaqueBinds[].image,pBindInfo[].pImageBinds[].image">const <type>VkBindSparseInfo</type>* <name>pBindInfo</name></param>
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <validity>
-                <usage>pname:fence must: be unsignaled</usage>
-                <usage>pname:fence must: not be associated with any other queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3370,9 +2857,6 @@
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>pname:fence must: not be associated with any queue command that has not yet completed execution on that queue</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:fence was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:fence was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3381,7 +2865,6 @@
             <param><type>uint32_t</type> <name>fenceCount</name></param>
             <param len="fenceCount" externsync="true">const <type>VkFence</type>* <name>pFences</name></param>
             <validity>
-                <usage>Any given element of pname:pFences must: not currently be associated with any queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_NOT_READY" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3410,9 +2893,6 @@
             <param optional="true" externsync="true"><type>VkSemaphore</type> <name>semaphore</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>pname:semaphore must: not be associated with any queue command that has not yet completed execution on that queue</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:semaphore was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:semaphore was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3428,9 +2908,6 @@
             <param optional="true" externsync="true"><type>VkEvent</type> <name>event</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:event must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:event was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:event was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_EVENT_SET,VK_EVENT_RESET" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3448,7 +2925,6 @@
             <param><type>VkDevice</type> <name>device</name></param>
             <param externsync="true"><type>VkEvent</type> <name>event</name></param>
             <validity>
-                <usage>pname:event must: not be waited on by a fname:vkCmdWaitEvents command that is currently executing</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3464,9 +2940,6 @@
             <param optional="true" externsync="true"><type>VkQueryPool</type> <name>queryPool</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:queryPool must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:queryPool was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:queryPool was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_NOT_READY" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST">
@@ -3480,12 +2953,6 @@
             <param><type>VkDeviceSize</type> <name>stride</name></param>
             <param optional="true"><type>VkQueryResultFlags</type> <name>flags</name></param>
             <validity>
-                <usage>pname:firstQuery must: be less than the number of queries in pname:queryPool</usage>
-                <usage>If ename:VK_QUERY_RESULT_64_BIT is not set in pname:flags then pname:pData and pname:stride must: be multiples of `4`</usage>
-                <usage>If ename:VK_QUERY_RESULT_64_BIT is set in pname:flags then pname:pData and pname:stride must: be multiples of `8`</usage>
-                <usage>The sum of pname:firstQuery and pname:queryCount must: be less than or equal to the number of queries in pname:queryPool</usage>
-                <usage>pname:dataSize must: be large enough to contain the result of each query, as described &lt;&lt;queries-operation-memorylayout,here&gt;&gt;</usage>
-                <usage>If the pname:queryType used to create pname:queryPool was ename:VK_QUERY_TYPE_TIMESTAMP, pname:flags must: not contain ename:VK_QUERY_RESULT_PARTIAL_BIT</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3495,7 +2962,6 @@
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <param><type>VkBuffer</type>* <name>pBuffer</name></param>
             <validity>
-                <usage>If the pname:flags member of pname:pCreateInfo includes ename:VK_BUFFER_CREATE_SPARSE_BINDING_BIT, creating this sname:VkBuffer must: not cause the total required sparse memory for all currently valid sparse resources on the device to exceed sname:VkPhysicalDeviceLimits::pname:sparseAddressSpaceSize</usage>
             </validity>
         </command>
         <command>
@@ -3504,9 +2970,6 @@
             <param optional="true" externsync="true"><type>VkBuffer</type> <name>buffer</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:buffer, either directly or via a sname:VkBufferView, must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:buffer was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:buffer was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3522,9 +2985,6 @@
             <param optional="true" externsync="true"><type>VkBufferView</type> <name>bufferView</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:bufferView must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:bufferView was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:bufferView was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3534,7 +2994,6 @@
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <param><type>VkImage</type>* <name>pImage</name></param>
             <validity>
-                <usage>If the pname:flags member of pname:pCreateInfo includes ename:VK_IMAGE_CREATE_SPARSE_BINDING_BIT, creating this sname:VkImage must: not cause the total required sparse memory for all currently valid sparse resources on the device to exceed sname:VkPhysicalDeviceLimits::pname:sparseAddressSpaceSize</usage>
             </validity>
         </command>
         <command>
@@ -3543,9 +3002,6 @@
             <param optional="true" externsync="true"><type>VkImage</type> <name>image</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:image, either directly or via a sname:VkImageView, must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:image was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:image was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command>
@@ -3555,8 +3011,6 @@
             <param>const <type>VkImageSubresource</type>* <name>pSubresource</name></param>
             <param><type>VkSubresourceLayout</type>* <name>pLayout</name></param>
             <validity>
-                <usage>pname:image must: have been created with pname:tiling equal to ename:VK_IMAGE_TILING_LINEAR</usage>
-                <usage>The pname:aspectMask member of pname:pSubresource must: only have a single bit set</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3572,9 +3026,6 @@
             <param optional="true" externsync="true"><type>VkImageView</type> <name>imageView</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:imageView must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:imageView was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:imageView was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
@@ -3590,8 +3041,6 @@
             <param optional="true" externsync="true"><type>VkShaderModule</type> <name>shaderModule</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:shaderModule was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:shaderModule was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3607,8 +3056,6 @@
             <param optional="true" externsync="true"><type>VkPipelineCache</type> <name>pipelineCache</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:pipelineCache was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:pipelineCache was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3625,7 +3072,6 @@
             <param><type>uint32_t</type> <name>srcCacheCount</name></param>
             <param len="srcCacheCount">const <type>VkPipelineCache</type>* <name>pSrcCaches</name></param>
             <validity>
-                <usage>pname:dstCache must: not appear in the list of source caches</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
@@ -3637,7 +3083,6 @@
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <param len="createInfoCount"><type>VkPipeline</type>* <name>pPipelines</name></param>
             <validity>
-                <usage>If the pname:flags member of any given element of pname:pCreateInfos contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the pname:basePipelineIndex member of that same element is not `-1`, pname:basePipelineIndex must: be less than the index into pname:pCreateInfos that corresponds to that element</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_INVALID_SHADER_NV">
@@ -3649,7 +3094,6 @@
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <param len="createInfoCount"><type>VkPipeline</type>* <name>pPipelines</name></param>
             <validity>
-                <usage>If the pname:flags member of any given element of pname:pCreateInfos contains the ename:VK_PIPELINE_CREATE_DERIVATIVE_BIT flag, and the pname:basePipelineIndex member of that same element is not `-1`, pname:basePipelineIndex must: be less than the index into pname:pCreateInfos that corresponds to that element</usage>
             </validity>
         </command>
         <command>
@@ -3658,9 +3102,6 @@
             <param optional="true" externsync="true"><type>VkPipeline</type> <name>pipeline</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:pipeline must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:pipeline was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:pipeline was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3676,8 +3117,6 @@
             <param optional="true" externsync="true"><type>VkPipelineLayout</type> <name>pipelineLayout</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:pipelineLayout was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:pipelineLayout was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_TOO_MANY_OBJECTS">
@@ -3693,9 +3132,6 @@
             <param optional="true" externsync="true"><type>VkSampler</type> <name>sampler</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:sampler must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:sampler was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:sampler was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3711,8 +3147,6 @@
             <param optional="true" externsync="true"><type>VkDescriptorSetLayout</type> <name>descriptorSetLayout</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:descriptorSetLayout was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:descriptorSetLayout was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3728,9 +3162,6 @@
             <param optional="true" externsync="true"><type>VkDescriptorPool</type> <name>descriptorPool</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:descriptorPool (via any allocated descriptor sets) must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:descriptorPool was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:descriptorPool was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3742,14 +3173,13 @@
                 <param>any sname:VkDescriptorSet objects allocated from pname:descriptorPool</param>
             </implicitexternsyncparams>
             <validity>
-                <usage>All uses of pname:descriptorPool (via any allocated descriptor sets) must: have completed execution</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_FRAGMENTED_POOL">
             <proto><type>VkResult</type> <name>vkAllocateDescriptorSets</name></proto>
             <param><type>VkDevice</type> <name>device</name></param>
-            <param externsync="pAllocateInfo->descriptorPool">const <type>VkDescriptorSetAllocateInfo</type>* <name>pAllocateInfo</name></param>
-            <param len="pAllocateInfo->descriptorSetCount"><type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
+            <param externsync="pAllocateInfo::descriptorPool">const <type>VkDescriptorSetAllocateInfo</type>* <name>pAllocateInfo</name></param>
+            <param len="pAllocateInfo::descriptorSetCount"><type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
             <proto><type>VkResult</type> <name>vkFreeDescriptorSets</name></proto>
@@ -3758,10 +3188,6 @@
             <param><type>uint32_t</type> <name>descriptorSetCount</name></param>
             <param noautovalidity="true" externsync="true" len="descriptorSetCount">const <type>VkDescriptorSet</type>* <name>pDescriptorSets</name></param>
             <validity>
-                <usage>All submitted commands that refer to any element of pname:pDescriptorSets must: have completed execution</usage>
-                <usage>pname:pDescriptorSets must: be a pointer to an array of pname:descriptorSetCount sname:VkDescriptorSet handles, each element of which must: either be a valid handle or dlink:VK_NULL_HANDLE</usage>
-                <usage>Each valid handle in pname:pDescriptorSets must: have been allocated from pname:descriptorPool</usage>
-                <usage>pname:descriptorPool must: have been created with the ename:VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT flag</usage>
             </validity>
         </command>
         <command>
@@ -3785,9 +3211,6 @@
             <param optional="true" externsync="true"><type>VkFramebuffer</type> <name>framebuffer</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:framebuffer must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:framebuffer was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:framebuffer was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3803,9 +3226,6 @@
             <param optional="true" externsync="true"><type>VkRenderPass</type> <name>renderPass</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All submitted commands that refer to pname:renderPass must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:renderPass was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:renderPass was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command>
@@ -3827,9 +3247,6 @@
             <param optional="true" externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All sname:VkCommandBuffer objects allocated from pname:commandPool must: not be pending execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:commandPool was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:commandPool was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3838,14 +3255,13 @@
             <param externsync="true"><type>VkCommandPool</type> <name>commandPool</name></param>
             <param optional="true"><type>VkCommandPoolResetFlags</type> <name>flags</name></param>
             <validity>
-                <usage>All sname:VkCommandBuffer objects allocated from pname:commandPool must: not currently be pending execution</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
             <proto><type>VkResult</type> <name>vkAllocateCommandBuffers</name></proto>
             <param><type>VkDevice</type> <name>device</name></param>
-            <param externsync="pAllocateInfo->commandPool">const <type>VkCommandBufferAllocateInfo</type>* <name>pAllocateInfo</name></param>
-            <param len="pAllocateInfo->commandBufferCount"><type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
+            <param externsync="pAllocateInfo::commandPool">const <type>VkCommandBufferAllocateInfo</type>* <name>pAllocateInfo</name></param>
+            <param len="pAllocateInfo::commandBufferCount"><type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
         </command>
         <command>
             <proto><type>void</type> <name>vkFreeCommandBuffers</name></proto>
@@ -3854,8 +3270,6 @@
             <param><type>uint32_t</type> <name>commandBufferCount</name></param>
             <param noautovalidity="true" externsync="true" len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
             <validity>
-                <usage>All elements of pname:pCommandBuffers must: not be pending execution</usage>
-                <usage>pname:pCommandBuffers must: be a pointer to an array of pname:commandBufferCount sname:VkCommandBuffer handles, each element of which must: either be a valid handle or dlink:VK_NULL_HANDLE</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3863,21 +3277,12 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param>const <type>VkCommandBufferBeginInfo</type>* <name>pBeginInfo</name></param>
             <validity>
-                <usage>pname:commandBuffer must: not be in the recording state</usage>
-                <usage>pname:commandBuffer must: not currently be pending execution</usage>
-                <usage>If pname:commandBuffer was allocated from a sname:VkCommandPool which did not have the ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT flag set, pname:commandBuffer must: be in the initial state</usage>
-                <usage>If pname:commandBuffer is a secondary command buffer, the pname:pInheritanceInfo member of pname:pBeginInfo must: be a valid sname:VkCommandBufferInheritanceInfo structure</usage>
-                <usage>If pname:commandBuffer is a secondary command buffer and either the pname:occlusionQueryEnable member of the pname:pInheritanceInfo member of pname:pBeginInfo is ename:VK_FALSE, or the precise occlusion queries feature is not enabled, the pname:queryFlags member of the pname:pInheritanceInfo member pname:pBeginInfo must: not contain ename:VK_QUERY_CONTROL_PRECISE_BIT</usage>
-
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
             <proto><type>VkResult</type> <name>vkEndCommandBuffer</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
-                <usage>pname:commandBuffer must: be in the recording state</usage>
-                <usage>If pname:commandBuffer is a primary command buffer, there must: not be an active render pass instance</usage>
-                <usage>All queries made &lt;&lt;queries-operation-active,active&gt;&gt; during the recording of pname:commandBuffer must: have been made inactive</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -3885,8 +3290,6 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param optional="true"><type>VkCommandBufferResetFlags</type> <name>flags</name></param>
             <validity>
-                <usage>pname:commandBuffer must: not currently be pending execution</usage>
-                <usage>pname:commandBuffer must: have been allocated from a pool that was created with the ename:VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3895,11 +3298,6 @@
             <param><type>VkPipelineBindPoint</type> <name>pipelineBindPoint</name></param>
             <param><type>VkPipeline</type> <name>pipeline</name></param>
             <validity>
-                <usage>If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_COMPUTE, the sname:VkCommandPool that pname:commandBuffer was allocated from must: support compute operations</usage>
-                <usage>If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_GRAPHICS, the sname:VkCommandPool that pname:commandBuffer was allocated from must: support graphics operations</usage>
-                <usage>If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_COMPUTE, pname:pipeline must: be a compute pipeline</usage>
-                <usage>If pname:pipelineBindPoint is ename:VK_PIPELINE_BIND_POINT_GRAPHICS, pname:pipeline must: be a graphics pipeline</usage>
-                <usage>If the &lt;&lt;features-features-variableMultisampleRate,variable multisample rate&gt;&gt; feature is not supported, pname:pipeline is a graphics pipeline, the current subpass has no attachments, and this is not the first call to this function with a graphics pipeline after transitioning to the current subpass, then the sample count specified by this pipeline must: match that set in the previous pipeline</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3909,9 +3307,6 @@
             <param><type>uint32_t</type> <name>viewportCount</name></param>
             <param len="viewportCount">const <type>VkViewport</type>* <name>pViewports</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_VIEWPORT dynamic state enabled</usage>
-                <usage>pname:firstViewport must: be less than sname:VkPhysicalDeviceLimits::pname:maxViewports</usage>
-                <usage>The sum of pname:firstViewport and pname:viewportCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3921,12 +3316,6 @@
             <param><type>uint32_t</type> <name>scissorCount</name></param>
             <param len="scissorCount">const <type>VkRect2D</type>* <name>pScissors</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_SCISSOR dynamic state enabled</usage>
-                <usage>pname:firstScissor must: be less than sname:VkPhysicalDeviceLimits::pname:maxViewports</usage>
-                <usage>The sum of pname:firstScissor and pname:scissorCount must: be between `1` and sname:VkPhysicalDeviceLimits::pname:maxViewports, inclusive</usage>
-                <usage>The pname:x and pname:y members of pname:offset must: be greater than or equal to `0`</usage>
-                <usage>Evaluation of (pname:offset.x + pname:extent.width) must: not cause a signed integer addition overflow</usage>
-                <usage>Evaluation of (pname:offset.y + pname:extent.height) must: not cause a signed integer addition overflow</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3934,8 +3323,6 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>float</type> <name>lineWidth</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_LINE_WIDTH dynamic state enabled</usage>
-                <usage>If the &lt;&lt;features-features-wideLines,wide lines&gt;&gt; feature is not enabled, pname:lineWidth must: be `1.0`</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3945,8 +3332,6 @@
             <param><type>float</type> <name>depthBiasClamp</name></param>
             <param><type>float</type> <name>depthBiasSlopeFactor</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_DEPTH_BIAS dynamic state enabled</usage>
-                <usage>If the &lt;&lt;features-features-depthBiasClamp,depth bias clamping&gt;&gt; feature is not enabled, pname:depthBiasClamp must: be code:0.0</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3954,7 +3339,6 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param>const <type>float</type> <name>blendConstants</name>[4]</param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_BLEND_CONSTANTS dynamic state enabled</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3963,9 +3347,6 @@
             <param><type>float</type> <name>minDepthBounds</name></param>
             <param><type>float</type> <name>maxDepthBounds</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_DEPTH_BOUNDS dynamic state enabled</usage>
-                <usage>pname:minDepthBounds must: be between `0.0` and `1.0`, inclusive</usage>
-                <usage>pname:maxDepthBounds must: be between `0.0` and `1.0`, inclusive</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3974,7 +3355,6 @@
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>compareMask</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK dynamic state enabled</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3983,7 +3363,6 @@
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>writeMask</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_WRITE_MASK dynamic state enabled</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -3992,7 +3371,6 @@
             <param><type>VkStencilFaceFlags</type> <name>faceMask</name></param>
             <param><type>uint32_t</type> <name>reference</name></param>
             <validity>
-                <usage>The currently bound graphics pipeline must: have been created with the ename:VK_DYNAMIC_STATE_STENCIL_REFERENCE dynamic state enabled</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4006,11 +3384,6 @@
             <param optional="true"><type>uint32_t</type> <name>dynamicOffsetCount</name></param>
             <param len="dynamicOffsetCount">const <type>uint32_t</type>* <name>pDynamicOffsets</name></param>
             <validity>
-                <usage>Any given element of pname:pDescriptorSets must: have been allocated with a sname:VkDescriptorSetLayout that matches (is the same as, or defined identically to) the sname:VkDescriptorSetLayout at set _n_ in pname:layout, where _n_ is the sum of pname:firstSet and the index into pname:pDescriptorSets</usage>
-                <usage>pname:dynamicOffsetCount must: be equal to the total number of dynamic descriptors in pname:pDescriptorSets</usage>
-                <usage>The sum of pname:firstSet and pname:descriptorSetCount must: be less than or equal to sname:VkPipelineLayoutCreateInfo::pname:setLayoutCount provided when pname:layout was created</usage>
-                <usage>pname:pipelineBindPoint must: be supported by the pname:commandBuffer's parent sname:VkCommandPool's queue family</usage>
-                <usage>Any given element of pname:pDynamicOffsets must: satisfy the required alignment for the corresponding descriptor binding's descriptor type</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4020,9 +3393,6 @@
             <param><type>VkDeviceSize</type> <name>offset</name></param>
             <param><type>VkIndexType</type> <name>indexType</name></param>
             <validity>
-                <usage>pname:offset must: be less than the size of pname:buffer</usage>
-                <usage>The sum of pname:offset and the address of the range of sname:VkDeviceMemory object that is backing pname:buffer, must: be a multiple of the type indicated by pname:indexType</usage>
-                <usage>pname:buffer must: have been created with the ename:VK_BUFFER_USAGE_INDEX_BUFFER_BIT flag</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4033,10 +3403,6 @@
             <param len="bindingCount">const <type>VkBuffer</type>* <name>pBuffers</name></param>
             <param len="bindingCount">const <type>VkDeviceSize</type>* <name>pOffsets</name></param>
             <validity>
-                <usage>pname:firstBinding must: be less than sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings</usage>
-                <usage>The sum of pname:firstBinding and pname:bindingCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxVertexInputBindings</usage>
-                <usage>All elements of pname:pOffsets must: be less than the size of the corresponding element in pname:pBuffers</usage>
-                <usage>All elements of pname:pBuffers must: have been created with the ename:VK_BUFFER_USAGE_VERTEX_BUFFER_BIT flag</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4047,20 +3413,6 @@
             <param><type>uint32_t</type> <name>firstVertex</name></param>
             <param><type>uint32_t</type> <name>firstInstance</name></param>
             <validity>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>For a given vertex buffer binding, any attribute data fetched must: be entirely contained within the corresponding vertex buffer binding, as described in &lt;&lt;fxvertex-input&gt;&gt;</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4072,21 +3424,6 @@
             <param><type>int32_t</type> <name>vertexOffset</name></param>
             <param><type>uint32_t</type> <name>firstInstance</name></param>
             <validity>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>For a given vertex buffer binding, any attribute data fetched must: be entirely contained within the corresponding vertex buffer binding, as described in &lt;&lt;fxvertex-input&gt;&gt;</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>(pname:indexSize * (pname:firstIndex + pname:indexCount) + pname:offset) must: be less than or equal to the size of the currently bound index buffer, with indexSize being based on the type specified by pname:indexType, where the index buffer, pname:indexType, and pname:offset are specified via fname:vkCmdBindIndexBuffer</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4097,26 +3434,6 @@
             <param><type>uint32_t</type> <name>drawCount</name></param>
             <param><type>uint32_t</type> <name>stride</name></param>
             <validity>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>If pname:drawCount is greater than `1`, pname:stride must: be a multiple of `4` and must: be greater than or equal to sizeof(sname:VkDrawIndirectCommand)</usage>
-                <usage>If the &lt;&lt;features-features-multiDrawIndirect,multi-draw indirect&gt;&gt; feature is not enabled, pname:drawCount must: be `0` or `1`</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, all the pname:firstInstance members of the sname:VkDrawIndirectCommand structures accessed by this command must: be code:0</usage>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>If pname:drawCount is equal to `1`, (pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If pname:drawCount is greater than `1`, (pname:stride x (pname:drawCount - 1) + pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>pname:drawCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxDrawIndirectCount</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4127,26 +3444,6 @@
             <param><type>uint32_t</type> <name>drawCount</name></param>
             <param><type>uint32_t</type> <name>stride</name></param>
             <validity>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>If pname:drawCount is greater than `1`, pname:stride must: be a multiple of `4` and must: be greater than or equal to sizeof(sname:VkDrawIndexedIndirectCommand)</usage>
-                <usage>If the &lt;&lt;features-features-multiDrawIndirect,multi-draw indirect&gt;&gt; feature is not enabled, pname:drawCount must: be `0` or `1`</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, all the pname:firstInstance members of the sname:VkDrawIndexedIndirectCommand structures accessed by this command must: be code:0</usage>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>If pname:drawCount is equal to `1`, (pname:offset + sizeof(sname:VkDrawIndexedIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If pname:drawCount is greater than `1`, (pname:stride x (pname:drawCount - 1) + pname:offset + sizeof(sname:VkDrawIndexedIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>pname:drawCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxDrawIndirectCount</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4156,19 +3453,6 @@
             <param><type>uint32_t</type> <name>y</name></param>
             <param><type>uint32_t</type> <name>z</name></param>
             <validity>
-                <usage>pname:x must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[0]</usage>
-                <usage>pname:y must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[1]</usage>
-                <usage>pname:z must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxComputeWorkGroupCount[2]</usage>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>A valid compute pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_COMPUTE</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that is compatible for push constants with the one used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4177,19 +3461,6 @@
             <param><type>VkBuffer</type> <name>buffer</name></param>
             <param><type>VkDeviceSize</type> <name>offset</name></param>
             <validity>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>A valid compute pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_COMPUTE</usage>
-                <usage>pname:buffer must: have been created with the ename:VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT bit set</usage>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>The sum of pname:offset and the size of sname:VkDispatchIndirectCommand must: be less than or equal to the size of pname:buffer</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_COMPUTE, with a sname:VkPipelineLayout that is compatible for push constants with the one used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_COMPUTE accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4200,14 +3471,6 @@
             <param><type>uint32_t</type> <name>regionCount</name></param>
             <param len="regionCount">const <type>VkBufferCopy</type>* <name>pRegions</name></param>
             <validity>
-                <usage>The pname:size member of a given element of pname:pRegions must: be greater than `0`</usage>
-                <usage>The pname:srcOffset member of a given element of pname:pRegions must: be less than the size of pname:srcBuffer</usage>
-                <usage>The pname:dstOffset member of a given element of pname:pRegions must: be less than the size of pname:dstBuffer</usage>
-                <usage>The pname:size member of a given element of pname:pRegions must: be less than or equal to the size of pname:srcBuffer minus pname:srcOffset</usage>
-                <usage>The pname:size member of a given element of pname:pRegions must: be less than or equal to the size of pname:dstBuffer minus pname:dstOffset</usage>
-                <usage>The union of the source regions, and the union of the destination regions, specified by the elements of pname:pRegions, must: not overlap in memory</usage>
-                <usage>pname:srcBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag</usage>
-                <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4220,17 +3483,6 @@
             <param><type>uint32_t</type> <name>regionCount</name></param>
             <param len="regionCount">const <type>VkImageCopy</type>* <name>pRegions</name></param>
             <validity>
-                <usage>The source region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcImage</usage>
-                <usage>The destination region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstImage</usage>
-                <usage>The union of all source regions, and the union of all destination regions, specified by the elements of pname:pRegions, must: not overlap in memory</usage>
-                <usage>pname:srcImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag</usage>
-                <usage>pname:srcImageLayout must: specify the layout of the image subresources of pname:srcImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:srcImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>pname:dstImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:dstImageLayout must: specify the layout of the image subresources of pname:dstImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:dstImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>The elink:VkFormat of each of pname:srcImage and pname:dstImage must: be compatible, as defined &lt;&lt;copies-images-format-compatibility, below&gt;&gt;</usage>
-                <usage>The sample count of pname:srcImage and pname:dstImage must: match</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4244,25 +3496,6 @@
             <param len="regionCount">const <type>VkImageBlit</type>* <name>pRegions</name></param>
             <param><type>VkFilter</type> <name>filter</name></param>
             <validity>
-                <usage>The source region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcImage</usage>
-                <usage>The destination region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstImage</usage>
-                <usage>The union of all destination regions, specified by the elements of pname:pRegions, must: not overlap in memory with any texel that may: be sampled during the blit operation</usage>
-                <usage>pname:srcImage must: use a format that supports ename:VK_FORMAT_FEATURE_BLIT_SRC_BIT, which is indicated by sname:VkFormatProperties::pname:linearTilingFeatures (for linear tiled images) or sname:VkFormatProperties::pname:optimalTilingFeatures (for optimally tiled images) - as returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage>pname:srcImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag</usage>
-                <usage>pname:srcImageLayout must: specify the layout of the image subresources of pname:srcImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:srcImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>pname:dstImage must: use a format that supports ename:VK_FORMAT_FEATURE_BLIT_DST_BIT, which is indicated by sname:VkFormatProperties::pname:linearTilingFeatures (for linear tiled images) or sname:VkFormatProperties::pname:optimalTilingFeatures (for optimally tiled images) - as returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage>pname:dstImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:dstImageLayout must: specify the layout of the image subresources of pname:dstImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:dstImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>The sample count of pname:srcImage and pname:dstImage must: both be equal to ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>If either of pname:srcImage or pname:dstImage was created with a signed integer elink:VkFormat, the other must: also have been created with a signed integer elink:VkFormat</usage>
-                <usage>If either of pname:srcImage or pname:dstImage was created with an unsigned integer elink:VkFormat, the other must: also have been created with an unsigned integer elink:VkFormat</usage>
-                <usage>If either of pname:srcImage or pname:dstImage was created with a depth/stencil format, the other must: have exactly the same format</usage>
-                <usage>If pname:srcImage was created with a depth/stencil format, pname:filter must: be ename:VK_FILTER_NEAREST</usage>
-                <usage>pname:srcImage must: have been created with a pname:samples value of ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>pname:dstImage must: have been created with a pname:samples value of ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>If pname:filter is ename:VK_FILTER_LINEAR, pname:srcImage must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4274,14 +3507,6 @@
             <param><type>uint32_t</type> <name>regionCount</name></param>
             <param len="regionCount">const <type>VkBufferImageCopy</type>* <name>pRegions</name></param>
             <validity>
-                <usage>The buffer region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcBuffer</usage>
-                <usage>The image region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstImage</usage>
-                <usage>The union of all source regions, and the union of all destination regions, specified by the elements of pname:pRegions, must: not overlap in memory</usage>
-                <usage>pname:srcBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_SRC_BIT usage flag</usage>
-                <usage>pname:dstImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:dstImage must: have a sample count equal to ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>pname:dstImageLayout must: specify the layout of the image subresources of pname:dstImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:dstImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4293,14 +3518,6 @@
             <param><type>uint32_t</type> <name>regionCount</name></param>
             <param len="regionCount">const <type>VkBufferImageCopy</type>* <name>pRegions</name></param>
             <validity>
-                <usage>The image region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcImage</usage>
-                <usage>The buffer region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstBuffer</usage>
-                <usage>The union of all source regions, and the union of all destination regions, specified by the elements of pname:pRegions, must: not overlap in memory</usage>
-                <usage>pname:srcImage must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT usage flag</usage>
-                <usage>pname:srcImage must: have a sample count equal to ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>pname:srcImageLayout must: specify the layout of the image subresources of pname:srcImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:srcImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4311,12 +3528,6 @@
             <param><type>VkDeviceSize</type> <name>dataSize</name></param>
             <param len="dataSize">const <type>void</type>* <name>pData</name></param>
             <validity>
-                <usage>pname:dstOffset must: be less than the size of pname:dstBuffer</usage>
-                <usage>pname:dataSize must: be less than or equal to the size of pname:dstBuffer minus pname:dstOffset</usage>
-                <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:dstOffset must: be a multiple of `4`</usage>
-                <usage>pname:dataSize must: be less than or equal to `65536`</usage>
-                <usage>pname:dataSize must: be a multiple of `4`</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4327,12 +3538,6 @@
             <param><type>VkDeviceSize</type> <name>size</name></param>
             <param><type>uint32_t</type> <name>data</name></param>
             <validity>
-                <usage>pname:dstOffset must: be less than the size of pname:dstBuffer</usage>
-                <usage>pname:dstOffset must: be a multiple of `4`</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be greater than `0`</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be less than or equal to the size of pname:dstBuffer minus pname:dstOffset</usage>
-                <usage>If pname:size is not equal to ename:VK_WHOLE_SIZE, pname:size must: be a multiple of `4`</usage>
-                <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4344,11 +3549,6 @@
             <param><type>uint32_t</type> <name>rangeCount</name></param>
             <param len="rangeCount">const <type>VkImageSubresourceRange</type>* <name>pRanges</name></param>
             <validity>
-                <usage>pname:image must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:imageLayout must: specify the layout of the image subresource ranges of pname:image specified in pname:pRanges at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:imageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>The image range of any given element of pname:pRanges must: be an image subresource range that is contained within pname:image</usage>
-                <usage>pname:image must: not have a compressed or depth/stencil format</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4360,11 +3560,6 @@
             <param><type>uint32_t</type> <name>rangeCount</name></param>
             <param len="rangeCount">const <type>VkImageSubresourceRange</type>* <name>pRanges</name></param>
             <validity>
-                <usage>pname:image must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>pname:imageLayout must: specify the layout of the image subresource ranges of pname:image specified in pname:pRanges at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:imageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>The image range of any given element of pname:pRanges must: be an image subresource range that is contained within pname:image</usage>
-                <usage>pname:image must: have a depth/stencil format</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4375,9 +3570,6 @@
             <param><type>uint32_t</type> <name>rectCount</name></param>
             <param len="rectCount">const <type>VkClearRect</type>* <name>pRects</name></param>
             <validity>
-                <usage>If the pname:aspectMask member of any given element of pname:pAttachments contains ename:VK_IMAGE_ASPECT_COLOR_BIT, the pname:colorAttachment member of those elements must: refer to a valid color attachment in the current subpass</usage>
-                <usage>The rectangular region specified by a given element of pname:pRects must: be contained within the render area of the current render pass instance</usage>
-                <usage>The layers specified by a given element of pname:pRects must: be contained within every attachment that pname:pAttachments refers to</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4390,18 +3582,6 @@
             <param><type>uint32_t</type> <name>regionCount</name></param>
             <param len="regionCount">const <type>VkImageResolve</type>* <name>pRegions</name></param>
             <validity>
-                <usage>The source region specified by a given element of pname:pRegions must: be a region that is contained within pname:srcImage</usage>
-                <usage>The destination region specified by a given element of pname:pRegions must: be a region that is contained within pname:dstImage</usage>
-                <usage>The union of all source regions, and the union of all destination regions, specified by the elements of pname:pRegions, must: not overlap in memory</usage>
-                <usage>pname:srcImage must: have a sample count equal to any valid sample count value other than ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>pname:dstImage must: have a sample count equal to ename:VK_SAMPLE_COUNT_1_BIT</usage>
-                <usage>pname:srcImageLayout must: specify the layout of the image subresources of pname:srcImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:srcImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>pname:dstImageLayout must: specify the layout of the image subresources of pname:dstImage specified in pname:pRegions at the time this command is executed on a sname:VkDevice</usage>
-                <usage>pname:dstImageLayout must: be either of ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL or ename:VK_IMAGE_LAYOUT_GENERAL</usage>
-                <usage>If pname:dstImage was created with pname:tiling equal to ename:VK_IMAGE_TILING_LINEAR, pname:dstImage must: have been created with a pname:format that supports being a color attachment, as specified by the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage>If pname:dstImage was created with pname:tiling equal to ename:VK_IMAGE_TILING_OPTIMAL, pname:dstImage must: have been created with a pname:format that supports being a color attachment, as specified by the ename:VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT flag in sname:VkFormatProperties::pname:optimalTilingFeatures returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4410,8 +3590,6 @@
             <param><type>VkEvent</type> <name>event</name></param>
             <param><type>VkPipelineStageFlags</type> <name>stageMask</name></param>
             <validity>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:stageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:stageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4420,9 +3598,6 @@
             <param><type>VkEvent</type> <name>event</name></param>
             <param><type>VkPipelineStageFlags</type> <name>stageMask</name></param>
             <validity>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:stageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:stageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>When this command executes, pname:event must: not be waited on by a fname:vkCmdWaitEvents command that is currently executing</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4439,12 +3614,6 @@
             <param optional="true"><type>uint32_t</type> <name>imageMemoryBarrierCount</name></param>
             <param len="imageMemoryBarrierCount">const <type>VkImageMemoryBarrier</type>* <name>pImageMemoryBarriers</name></param>
             <validity>
-                <usage>pname:srcStageMask must: be the bitwise OR of the pname:stageMask parameter used in previous calls to fname:vkCmdSetEvent with any of the members of pname:pEvents and ename:VK_PIPELINE_STAGE_HOST_BIT if any of the members of pname:pEvents was set using fname:vkSetEvent</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>If pname:pEvents includes one or more events that will be signaled by fname:vkSetEvent after pname:commandBuffer has been submitted to a queue, then fname:vkCmdWaitEvents must: not be called inside a render pass instance</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4459,23 +3628,6 @@
             <param len="bufferMemoryBarrierCount">const <type>VkBufferMemoryBarrier</type>* <name>pBufferMemoryBarriers</name></param>
             <param optional="true"><type>uint32_t</type> <name>imageMemoryBarrierCount</name></param>
             <param len="imageMemoryBarrierCount">const <type>VkImageMemoryBarrier</type>* <name>pImageMemoryBarriers</name></param>
-            <validity>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-geometryShader,geometry shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:srcStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>If the &lt;&lt;features-features-tessellationShader,tessellation shaders&gt;&gt; feature is not enabled, pname:dstStageMask must: not contain ename:VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT or ename:VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, the render pass must: have been created with a sname:VkSubpassDependency instance in pname:pDependencies that expresses a dependency from the current subpass to itself. Additionally:
-                    ** pname:srcStageMask must: contain a subset of the bit values in the pname:srcStageMask member of that instance of sname:VkSubpassDependency
-                    ** pname:dstStageMask must: contain a subset of the bit values in the pname:dstStageMask member of that instance of sname:VkSubpassDependency
-                    ** The pname:srcAccessMask of any element of pname:pMemoryBarriers or pname:pImageMemoryBarriers must: contain a subset of the bit values the pname:srcAccessMask member of that instance of sname:VkSubpassDependency
-                    ** The pname:dstAccessMask of any element of pname:pMemoryBarriers or pname:pImageMemoryBarriers must: contain a subset of the bit values the pname:dstAccessMask member of that instance of sname:VkSubpassDependency
-                    ** pname:dependencyFlags must: be equal to the pname:dependencyFlags member of that instance of sname:VkSubpassDependency</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, pname:bufferMemoryBarrierCount must: be `0`</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, the pname:image member of any element of pname:pImageMemoryBarriers must: be equal to one of the elements of pname:pAttachments that the current pname:framebuffer was created with, that is also referred to by one of the elements of the pname:pColorAttachments, pname:pResolveAttachments or pname:pDepthStencilAttachment members of the sname:VkSubpassDescription instance that the current subpass was created with</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, the pname:oldLayout and pname:newLayout members of any element of pname:pImageMemoryBarriers must: be equal to the pname:layout member of an element of the pname:pColorAttachments, pname:pResolveAttachments or pname:pDepthStencilAttachment members of the sname:VkSubpassDescription instance that the current subpass was created with, that refers to the same pname:image</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, the pname:oldLayout and pname:newLayout members of an element of pname:pImageMemoryBarriers must: be equal</usage>
-                <usage>If fname:vkCmdPipelineBarrier is called within a render pass instance, the pname:srcQueueFamilyIndex and pname:dstQueueFamilyIndex members of any element of pname:pImageMemoryBarriers must: be ename:VK_QUEUE_FAMILY_IGNORED</usage>
-            </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
             <proto><type>void</type> <name>vkCmdBeginQuery</name></proto>
@@ -4484,14 +3636,6 @@
             <param><type>uint32_t</type> <name>query</name></param>
             <param optional="true"><type>VkQueryControlFlags</type> <name>flags</name></param>
             <validity>
-                <usage>The query identified by pname:queryPool and pname:query must: currently not be &lt;&lt;queries-operation-active,active&gt;&gt;</usage>
-                <usage>The query identified by pname:queryPool and pname:query must: be unavailable</usage>
-                <usage>If the &lt;&lt;features-features-occlusionQueryPrecise,precise occlusion queries&gt;&gt; feature is not enabled, or the pname:queryType used to create pname:queryPool was not ename:VK_QUERY_TYPE_OCCLUSION, pname:flags must: not contain ename:VK_QUERY_CONTROL_PRECISE_BIT</usage>
-                <usage>pname:queryPool must: have been created with a pname:queryType that differs from that of any other queries that have been made &lt;&lt;queries-operation-active,active&gt;&gt;, and are currently still active within pname:commandBuffer</usage>
-                <usage>pname:query must: be less than the number of queries in pname:queryPool</usage>
-                <usage>If the pname:queryType used to create pname:queryPool was ename:VK_QUERY_TYPE_OCCLUSION, the sname:VkCommandPool that pname:commandBuffer was allocated from must: support graphics operations</usage>
-                <usage>If the pname:queryType used to create pname:queryPool was ename:VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pname:pipelineStatistics indicate graphics operations, the sname:VkCommandPool that pname:commandBuffer was allocated from must: support graphics operations</usage>
-                <usage>If the pname:queryType used to create pname:queryPool was ename:VK_QUERY_TYPE_PIPELINE_STATISTICS and any of the pname:pipelineStatistics indicate compute operations, the sname:VkCommandPool that pname:commandBuffer was allocated from must: support compute operations</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4500,8 +3644,6 @@
             <param><type>VkQueryPool</type> <name>queryPool</name></param>
             <param><type>uint32_t</type> <name>query</name></param>
             <validity>
-                <usage>The query identified by pname:queryPool and pname:query must: currently be &lt;&lt;queries-operation-active,active&gt;&gt;</usage>
-                <usage>pname:query must: be less than the number of queries in pname:queryPool</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4511,8 +3653,6 @@
             <param><type>uint32_t</type> <name>firstQuery</name></param>
             <param><type>uint32_t</type> <name>queryCount</name></param>
             <validity>
-                <usage>pname:firstQuery must: be less than the number of queries in pname:queryPool</usage>
-                <usage>The sum of pname:firstQuery and pname:queryCount must: be less than or equal to the number of queries in pname:queryPool</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4522,8 +3662,6 @@
             <param><type>VkQueryPool</type> <name>queryPool</name></param>
             <param><type>uint32_t</type> <name>query</name></param>
             <validity>
-                <usage>The query identified by pname:queryPool and pname:query must: be _unavailable_</usage>
-                <usage>The command pool's queue family must: support a non-zero pname:timestampValidBits</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="outside" cmdbufferlevel="primary,secondary">
@@ -4537,14 +3675,6 @@
             <param><type>VkDeviceSize</type> <name>stride</name></param>
             <param optional="true"><type>VkQueryResultFlags</type> <name>flags</name></param>
             <validity>
-                <usage>pname:dstOffset must: be less than the size of pname:dstBuffer</usage>
-                <usage>pname:firstQuery must: be less than the number of queries in pname:queryPool</usage>
-                <usage>The sum of pname:firstQuery and pname:queryCount must: be less than or equal to the number of queries in pname:queryPool</usage>
-                <usage>If ename:VK_QUERY_RESULT_64_BIT is not set in pname:flags then pname:dstOffset and pname:stride must: be multiples of `4`</usage>
-                <usage>If ename:VK_QUERY_RESULT_64_BIT is set in pname:flags then pname:dstOffset and pname:stride must: be multiples of `8`</usage>
-                <usage>pname:dstBuffer must: have enough storage, from pname:dstOffset, to contain the result of each query, as described &lt;&lt;queries-operation-memorylayout,here&gt;&gt;</usage>
-                <usage>pname:dstBuffer must: have been created with ename:VK_BUFFER_USAGE_TRANSFER_DST_BIT usage flag</usage>
-                <usage>If the pname:queryType used to create pname:queryPool was ename:VK_QUERY_TYPE_TIMESTAMP, pname:flags must: not contain ename:VK_QUERY_RESULT_PARTIAL_BIT</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4556,11 +3686,6 @@
             <param><type>uint32_t</type> <name>size</name></param>
             <param len="size">const <type>void</type>* <name>pValues</name></param>
             <validity>
-                <usage>pname:stageFlags must: match exactly the shader stages used in pname:layout for the range specified by pname:offset and pname:size</usage>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>pname:size must: be a multiple of `4`</usage>
-                <usage>pname:offset must: be less than sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize</usage>
-                <usage>pname:size must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxPushConstantsSize minus pname:offset</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="outside" cmdbufferlevel="primary">
@@ -4569,12 +3694,6 @@
             <param>const <type>VkRenderPassBeginInfo</type>* <name>pRenderPassBegin</name></param>
             <param><type>VkSubpassContents</type> <name>contents</name></param>
             <validity>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL or ename:VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_SAMPLED_BIT or ename:VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_SRC_BIT set</usage>
-                <usage>If any of the pname:initialLayout or pname:finalLayout member of the sname:VkAttachmentDescription structures or the pname:layout member of the sname:VkAttachmentReference structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is ename:VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL then the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin must: have been created with ename:VK_IMAGE_USAGE_TRANSFER_DST_BIT set</usage>
-                <usage>If any of the pname:initialLayout members of the sname:VkAttachmentDescription structures specified when creating the render pass specified in the pname:renderPass member of pname:pRenderPassBegin is not ename:VK_IMAGE_LAYOUT_UNDEFINED, then each such pname:initialLayout must: be equal to the current layout of the corresponding attachment image subresource of the framebuffer specified in the pname:framebuffer member of pname:pRenderPassBegin</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary">
@@ -4582,14 +3701,12 @@
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <param><type>VkSubpassContents</type> <name>contents</name></param>
             <validity>
-                <usage>The current subpass index must: be less than the number of subpasses in the render pass minus one</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary">
             <proto><type>void</type> <name>vkCmdEndRenderPass</name></proto>
             <param externsync="true"><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
-                <usage>The current subpass index must: be equal to the number of subpasses in the render pass minus one</usage>
             </validity>
         </command>
         <command queues="transfer,graphics,compute" renderpass="both" cmdbufferlevel="primary">
@@ -4598,23 +3715,6 @@
             <param><type>uint32_t</type> <name>commandBufferCount</name></param>
             <param len="commandBufferCount">const <type>VkCommandBuffer</type>* <name>pCommandBuffers</name></param>
             <validity>
-                <usage>pname:commandBuffer must: have been allocated with a pname:level of ename:VK_COMMAND_BUFFER_LEVEL_PRIMARY</usage>
-                <usage>Any given element of pname:pCommandBuffers must: have been allocated with a pname:level of ename:VK_COMMAND_BUFFER_LEVEL_SECONDARY</usage>
-                <usage>Any given element of pname:pCommandBuffers must: not be already pending execution in pname:commandBuffer, or appear twice in pname:pCommandBuffers, unless it was recorded with the ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag</usage>
-                <usage>Any given element of pname:pCommandBuffers must: not be already pending execution in any other sname:VkCommandBuffer, unless it was recorded with the ename:VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag</usage>
-                <usage>Any given element of pname:pCommandBuffers must: be in the executable state</usage>
-                <usage>Any given element of pname:pCommandBuffers must: have been allocated from a sname:VkCommandPool that was created for the same queue family as the sname:VkCommandPool from which pname:commandBuffer was allocated</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, that render pass instance must: have been begun with the pname:contents parameter of fname:vkCmdBeginRenderPass set to ename:VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with the ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:subpass set to the index of the subpass which the given command buffer will be executed in</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, any given element of pname:pCommandBuffers must: have been recorded with a render pass that is compatible with the current render pass - see &lt;&lt;renderpass-compatibility&gt;&gt;</usage>
-                <usage>If fname:vkCmdExecuteCommands is being called within a render pass instance, and any given element of pname:pCommandBuffers was recorded with sname:VkCommandBufferInheritanceInfo::pname:framebuffer not equal to dlink:VK_NULL_HANDLE, that sname:VkFramebuffer must: match the sname:VkFramebuffer used in the current render pass instance</usage>
-                <usage>If fname:vkCmdExecuteCommands is not being called within a render pass instance, any given element of pname:pCommandBuffers must: not have been recorded with the ename:VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT</usage>
-                <usage>If the &lt;&lt;features-features-inheritedQueries,inherited queries&gt;&gt; feature is not enabled, pname:commandBuffer must: not have any queries &lt;&lt;queries-operation-active,active&gt;&gt;</usage>
-                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:occlusionQueryEnable set to ename:VK_TRUE</usage>
-                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_OCCLUSION query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:queryFlags having all bits set that are set for the query</usage>
-                <usage>If pname:commandBuffer has a ename:VK_QUERY_TYPE_PIPELINE_STATISTICS query &lt;&lt;queries-operation-active,active&gt;&gt;, then each element of pname:pCommandBuffers must: have been recorded with sname:VkCommandBufferInheritanceInfo::pname:pipelineStatistics having all bits set that are set in the sname:VkQueryPool the query uses</usage>
-                <usage>Any given element of pname:pCommandBuffers must: not begin any query types that are &lt;&lt;queries-operation-active,active&gt;&gt; in pname:commandBuffer</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_NATIVE_WINDOW_IN_USE_KHR">
@@ -4643,7 +3743,6 @@
             <param optional="false,true"><type>uint32_t</type>* <name>pDisplayCount</name></param>
             <param optional="true" len="pDisplayCount"><type>VkDisplayKHR</type>* <name>pDisplays</name></param>
             <validity>
-                <usage>pname:planeIndex must: be less than the number of display planes supported by the device as determined by calling fname:vkGetPhysicalDeviceDisplayPlanePropertiesKHR</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4696,7 +3795,6 @@
             <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
             <param><type>MirConnection</type>* <name>connection</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command>
@@ -4705,9 +3803,6 @@
             <param optional="true" externsync="true"><type>VkSurfaceKHR</type> <name>surface</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All sname:VkSwapchainKHR objects created for pname:surface must: have been destroyed prior to destroying pname:surface</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:surface was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:surface was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
@@ -4717,7 +3812,6 @@
             <param><type>VkSurfaceKHR</type> <name>surface</name></param>
             <param><type>VkBool32</type>* <name>pSupported</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_SURFACE_LOST_KHR">
@@ -4753,9 +3847,6 @@
             <param optional="true" externsync="true"><type>VkSwapchainKHR</type> <name>swapchain</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-                <usage>All uses of presentable images acquired from pname:swapchain must: have completed execution</usage>
-                <usage>If sname:VkAllocationCallbacks were provided when pname:swapchain was created, a compatible set of callbacks must: be provided here</usage>
-                <usage>If no sname:VkAllocationCallbacks were provided when pname:swapchain was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_INCOMPLETE" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4774,8 +3865,6 @@
             <param optional="true" externsync="true"><type>VkFence</type> <name>fence</name></param>
             <param><type>uint32_t</type>* <name>pImageIndex</name></param>
             <validity>
-                <usage>If pname:semaphore is not dlink:VK_NULL_HANDLE it must: be unsignaled</usage>
-                <usage>If pname:fence is not dlink:VK_NULL_HANDLE it must: be unsignaled and must: not be associated with any other queue command that has not yet completed execution on that queue</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS,VK_SUBOPTIMAL_KHR" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY,VK_ERROR_DEVICE_LOST,VK_ERROR_OUT_OF_DATE_KHR,VK_ERROR_SURFACE_LOST_KHR">
@@ -4783,7 +3872,6 @@
             <param externsync="true"><type>VkQueue</type> <name>queue</name></param>
             <param externsync="pPresentInfo.pWaitSemaphores[],pPresentInfo.pSwapchains[]">const <type>VkPresentInfoKHR</type>* <name>pPresentInfo</name></param>
             <validity>
-                <usage>Any given element of pname:pSwapchains member of pname:pPresentInfo must: be a swapchain that is created for a surface for which presentation is supported from pname:queue as determined using a call to fname:vkGetPhysicalDeviceSurfaceSupportKHR</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4799,7 +3887,6 @@
             <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
             <param>struct <type>wl_display</type>* <name>display</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4814,7 +3901,6 @@
             <param><type>VkPhysicalDevice</type> <name>physicalDevice</name></param>
             <param><type>uint32_t</type> <name>queueFamilyIndex</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4831,7 +3917,6 @@
             <param><type>Display</type>* <name>dpy</name></param>
             <param><type>VisualID</type> <name>visualID</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4848,7 +3933,6 @@
             <param><type>xcb_connection_t</type>* <name>connection</name></param>
             <param><type>xcb_visualid_t</type> <name>visual_id</name></param>
             <validity>
-                <usage>pname:queueFamilyIndex must: be less than pname:pQueueFamilyPropertyCount returned by fname:vkGetPhysicalDeviceQueueFamilyProperties for the given pname:physicalDevice</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY">
@@ -4864,8 +3948,6 @@
             <param externsync="true"><type>VkDebugReportCallbackEXT</type> <name>callback</name></param>
             <param optional="true">const <type>VkAllocationCallbacks</type>* <name>pAllocator</name></param>
             <validity>
-               <usage>If sname:VkAllocationCallbacks were provided when pname:instance was created, a compatible set of callbacks must: be provided here</usage>
-               <usage>If no sname:VkAllocationCallbacks were provided when pname:instance was created, pname:pAllocator must: be `NULL`</usage>
             </validity>
         </command>
         <command>
@@ -4879,12 +3961,6 @@
             <param>const <type>char</type>* <name>pLayerPrefix</name></param>
             <param>const <type>char</type>* <name>pMessage</name></param>
             <validity>
-               <usage>pname:instance must: be a valid sname:VkInstance handle</usage>
-               <usage>pname:flags must: be a combination of one or more of sname:VkDebugReportFlagBitsEXT</usage>
-               <usage>pname:objType must: be one of sname:VkDebugReportObjectTypeEXT, ename:VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT if pname:object is `NULL`</usage>
-               <usage>pname:object may: be a Vulkan object</usage>
-               <usage>pname:pLayerPrefix must: be a `NULL` terminated string</usage>
-               <usage>pname:pMsg must: be a `NULL` terminated string</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4892,7 +3968,6 @@
             <param><type>VkDevice</type> <name>device</name></param>
             <param externsync="pNameInfo.object"><type>VkDebugMarkerObjectNameInfoEXT</type>* <name>pNameInfo</name></param>
             <validity>
-               <usage>pname:pNameInfo.object must: be a Vulkan object</usage>
             </validity>
         </command>
         <command successcodes="VK_SUCCESS" errorcodes="VK_ERROR_OUT_OF_HOST_MEMORY,VK_ERROR_OUT_OF_DEVICE_MEMORY">
@@ -4900,8 +3975,6 @@
             <param><type>VkDevice</type> <name>device</name></param>
             <param externsync="pTagInfo.object"><type>VkDebugMarkerObjectTagInfoEXT</type>* <name>pTagInfo</name></param>
             <validity>
-               <usage>pname:pTagInfo.object must: be a Vulkan object</usage>
-               <usage>pname:pTagInfo.tagName must: not be `0`</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4913,8 +3986,6 @@
             <proto><type>void</type> <name>vkCmdDebugMarkerEndEXT</name></proto>
             <param><type>VkCommandBuffer</type> <name>commandBuffer</name></param>
             <validity>
-                <usage>There must: be an outstanding flink:vkCmdDebugMarkerBeginEXT command prior to the fname:vkCmdDebugMarkerEndEXT on the queue that pname:commandBuffer is submitted to</usage>
-                <usage>If the matching flink:vkCmdDebugMarkerBeginEXT command was in a secondary command buffer, the fname:vkCmdDebugMarkerEndEXT must be in the same pname:commandBuffer</usage>
             </validity>
         </command>
         <command queues="graphics,compute" renderpass="both" cmdbufferlevel="primary,secondary">
@@ -4940,7 +4011,6 @@
             <param><type>VkExternalMemoryHandleTypeFlagsNV</type> <name>handleType</name></param>
             <param><type>HANDLE</type>* <name>pHandle</name></param>
             <validity>
-                <usage>pname:handleType must: be a flag specified in slink:VkExportMemoryAllocateInfoNV::pname:handleTypes when allocating pname:memory</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4953,27 +4023,6 @@
             <param><type>uint32_t</type> <name>maxDrawCount</name></param>
             <param><type>uint32_t</type> <name>stride</name></param>
             <validity>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>pname:countBufferOffset must: be a multiple of `4`</usage>
-                <usage>pname:stride must: be a multiple of `4` and must: be greater than or equal to sizeof(sname:VkDrawIndirectCommand)</usage>
-                <usage>If pname:maxDrawCount is greater than or equal to `1`, (pname:stride x (pname:maxDrawCount - 1) + pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, all the pname:firstInstance members of the sname:VkDrawIndirectCommand structures accessed by this command must: be code:0</usage>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>If the count stored in pname:countBuffer is equal to `1`, (pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If the count stored in pname:countBuffer is greater than `1`, (pname:stride x (pname:drawCount - 1) + pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>The count stored in pname:countBuffer must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxDrawIndirectCount</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
         <command queues="graphics" renderpass="inside" cmdbufferlevel="primary,secondary">
@@ -4986,27 +4035,6 @@
             <param><type>uint32_t</type> <name>maxDrawCount</name></param>
             <param><type>uint32_t</type> <name>stride</name></param>
             <validity>
-                <usage>pname:offset must: be a multiple of `4`</usage>
-                <usage>pname:countBufferOffset must: be a multiple of `4`</usage>
-                <usage>pname:stride must: be a multiple of `4` and must: be greater than or equal to sizeof(sname:VkDrawIndirectCommand)</usage>
-                <usage>If pname:maxDrawCount is greater than or equal to `1`, (pname:stride x (pname:maxDrawCount - 1) + pname:offset + sizeof(sname:VkDrawIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If the &lt;&lt;features-features-drawIndirectFirstInstance,drawIndirectFirstInstance&gt;&gt; feature is not enabled, all the pname:firstInstance members of the sname:VkDrawIndexedIndirectCommand structures accessed by this command must: be code:0</usage>
-                <usage>For each set _n_ that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a descriptor set must: have been bound to _n_ at ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for set _n_, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>For each push constant that is statically used by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS, a push constant value must: have been set for ename:VK_PIPELINE_BIND_POINT_GRAPHICS, with a sname:VkPipelineLayout that is compatible for push constants, with the sname:VkPipelineLayout used to create the current sname:VkPipeline, as described in &lt;&lt;descriptorsets-compatibility&gt;&gt;</usage>
-                <usage>Descriptors in each bound descriptor set, specified via fname:vkCmdBindDescriptorSets, must: be valid if they are statically used by the currently bound sname:VkPipeline object, specified via fname:vkCmdBindPipeline</usage>
-                <usage>All vertex input bindings accessed via vertex input variables declared in the vertex shader entry point's interface must: have valid buffers bound</usage>
-                <usage>A valid graphics pipeline must: be bound to the current command buffer with ename:VK_PIPELINE_BIND_POINT_GRAPHICS</usage>
-                <usage>If the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS requires any dynamic state, that state must: have been set on the current command buffer</usage>
-                <usage>If count stored in pname:countBuffer is equal to `1`, (pname:offset + sizeof(sname:VkDrawIndexedIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>If count stored in pname:countBuffer is greater than `1`, (pname:stride x (pname:drawCount - 1) + pname:offset + sizeof(sname:VkDrawIndexedIndirectCommand)) must: be less than or equal to the size of pname:buffer</usage>
-                <usage>pname:drawCount must: be less than or equal to sname:VkPhysicalDeviceLimits::pname:maxDrawIndirectCount</usage>
-                <usage>Every input attachment used by the current subpass must: be bound to the pipeline via a descriptor set</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used to sample from any sname:VkImage with a sname:VkImageView of the type ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, ename:VK_IMAGE_VIEW_TYPE_1D_ARRAY, ename:VK_IMAGE_VIEW_TYPE_2D_ARRAY or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions with code:ImplicitLod, code:Dref or code:Proj in their name, in any shader stage</usage>
-                <usage>If any sname:VkSampler object that is accessed from a shader by the sname:VkPipeline currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS uses unnormalized coordinates, it must: not be used with any of the SPIR-V `OpImageSample*` or `OpImageSparseSample*` instructions that includes a LOD bias or any offset values, in any shader stage</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a uniform buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>If the &lt;&lt;features-features-robustBufferAccess,robust buffer access&gt;&gt; feature is not enabled, and any shader stage in the sname:VkPipeline object currently bound to ename:VK_PIPELINE_BIND_POINT_GRAPHICS accesses a storage buffer, it must: not access values outside of the range of that buffer specified in the currently bound descriptor set</usage>
-                <usage>Any sname:VkImageView being sampled with ename:VK_FILTER_LINEAR as a result of this command must: be of a format which supports linear filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
             </validity>
         </command>
     </commands>
@@ -5138,7 +4166,6 @@
             <command name="vkGetPipelineCacheData"/>
             <command name="vkMergePipelineCaches"/>
         </require>
-
         <require comment="Pipeline commands">
             <command name="vkCreateGraphicsPipelines"/>
             <command name="vkCreateComputePipelines"/>
@@ -5306,7 +4333,6 @@
                 <enum offset="1" dir="-" extends="VkResult"             name="VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"/>
                 <type name="VkDisplayPresentInfoKHR"/>
                 <command name="vkCreateSharedSwapchainsKHR"/>
-                <usage command="vkQueuePresentKHR">If more than one member of 'pSwapchains' was created from a display surface, all display surfaces referenced that refer to the same display must: use the same display mode</usage>
             </require>
         </extension>
         <extension name="VK_KHR_xlib_surface" number="5" type="instance" requires="VK_KHR_surface" protect="VK_USE_PLATFORM_XLIB_KHR" supported="vulkan">
@@ -5381,7 +4407,7 @@
                 <enum value="&quot;VK_ANDROID_native_buffer&quot;"      name="VK_ANDROID_NATIVE_BUFFER_NAME"/>
             </require>
         </extension>
-        <extension name="VK_EXT_debug_report" number="12" author="Google, Inc." contact="Courtney Goeltzenleuchter @courtney" supported="vulkan">
+        <extension name="VK_EXT_debug_report" number="12" type="instance" author="Google, Inc." contact="Courtney Goeltzenleuchter @courtney" supported="vulkan">
             <require>
                 <enum value="3"                                         name="VK_EXT_DEBUG_REPORT_SPEC_VERSION"/>
                 <enum value="&quot;VK_EXT_debug_report&quot;"           name="VK_EXT_DEBUG_REPORT_EXTENSION_NAME"/>
@@ -5422,21 +4448,6 @@
                 <enum value="&quot;VK_IMG_filter_cubic&quot;"           name="VK_IMG_FILTER_CUBIC_EXTENSION_NAME"/>
                 <enum offset="0" extends="VkFilter"                     name="VK_FILTER_CUBIC_IMG"/>
                 <enum bitpos="13" extends="VkFormatFeatureFlagBits"     name="VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG" comment="Format can be filtered with VK_FILTER_CUBIC_IMG when being sampled"/>
-                <usage command="vkCmdDraw">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDraw">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdDrawIndexed">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDrawIndexed">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdDrawIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDrawIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdDrawIndexedIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDrawIndexedIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdDispatch">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDispatch">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdDispatchIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdDispatchIndirect">Any slink:VkImageView being sampled with ename:VK_FILTER_CUBIC_IMG as a result of this command must: not have a elink:VkImageViewType of ename:VK_IMAGE_VIEW_TYPE_3D, ename:VK_IMAGE_VIEW_TYPE_CUBE, or ename:VK_IMAGE_VIEW_TYPE_CUBE_ARRAY</usage>
-                <usage command="vkCmdBlitImage">If pname:filter is ename:VK_FILTER_CUBIC_IMG, pname:srcImage must: be of a format which supports cubic filtering, as specified by the ename:VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_IMG flag in sname:VkFormatProperties::pname:linearTilingFeatures (for a linear image) or sname:VkFormatProperties::pname:optimalTilingFeatures(for an optimally tiled image) returned by fname:vkGetPhysicalDeviceFormatProperties</usage>
-                <usage command="vkCmdBlitImage">If pname:filter is ename:VK_FILTER_CUBIC_IMG, pname:srcImage must: have a elink:VkImageType of ename:VK_IMAGE_TYPE_3D</usage>
-                <usage struct="VkSamplerCreateInfo">If either pname:magFilter or pname:minFilter is ename:VK_FILTER_CUBIC_IMG, pname:anisotropyEnable must: be ename:VK_FALSE</usage>
             </require>
         </extension>
         <extension name="VK_AMD_extension_17" number="17" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
@@ -5478,7 +4489,7 @@
                 <enum value="&quot;VK_AMD_shader_explicit_vertex_parameter&quot;" name="VK_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_EXT_debug_marker" number="23" author="Baldur Karlsson" contact="baldurk@baldurk.org" type="device" supported="vulkan">
+        <extension name="VK_EXT_debug_marker" number="23" type="device" author="Baldur Karlsson" contact="baldurk@baldurk.org" supported="vulkan">
             <require>
                 <enum value="3"                                         name="VK_EXT_DEBUG_MARKER_SPEC_VERSION"/>
                 <enum value="&quot;VK_EXT_debug_marker&quot;"           name="VK_EXT_DEBUG_MARKER_EXTENSION_NAME"/>
@@ -5523,10 +4534,6 @@
                 <type name="VkDedicatedAllocationImageCreateInfoNV"/>
                 <type name="VkDedicatedAllocationBufferCreateInfoNV"/>
                 <type name="VkDedicatedAllocationMemoryAllocateInfoNV"/>
-                <usage command="vkBindBufferMemory">If pname:buffer was created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: have been created with sname:VkDedicatedAllocationMemoryAllocateInfoNV::pname:buffer equal to pname:buffer and pname:memoryOffset must: be zero</usage>
-                <usage command="vkBindBufferMemory">If pname:buffer was not created with sname:VkDedicatedAllocationBufferCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: not have been allocated dedicated for a specific buffer or image</usage>
-                <usage command="vkBindImageMemory">If pname:image was created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: have been created with sname:VkDedicatedAllocationMemoryAllocateInfoNV::pname:image equal to pname:image and pname:memoryOffset must: be zero</usage>
-                <usage command="vkBindImageMemory">If pname:image was not created with sname:VkDedicatedAllocationImageCreateInfoNV::pname:dedicatedAllocation equal to ename:VK_TRUE, pname:memory must: not have been allocated dedicated for a specific buffer or image</usage>
             </require>
         </extension>
         <extension name="VK_EXT_extension_28" number="28" author="NVIDIA" contact="Piers Daniell @pdaniell" supported="disabled">
@@ -5567,8 +4574,8 @@
         </extension>
         <extension name="VK_AMD_draw_indirect_count" number="34" type="device" author="AMD" contact="Daniel Rakos @aqnuep" supported="vulkan">
             <require>
-                <enum value="1"                                         name="VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_draw_indirect_count&quot;"    name="VK_AMD_EXTENSION_DRAW_INDIRECT_COUNT_EXTENSION_NAME"/>
+                <enum value="1"                                         name="VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_draw_indirect_count&quot;"    name="VK_AMD_DRAW_INDIRECT_COUNT_EXTENSION_NAME"/>
                 <command name="vkCmdDrawIndirectCountAMD"/>
                 <command name="vkCmdDrawIndexedIndirectCountAMD"/>
             </require>
@@ -5579,22 +4586,22 @@
                 <enum value="&quot;VK_AMD_extension_35&quot;"           name="VK_AMD_EXTENSION_35_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_36" number="36" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_negative_viewport_height" number="36" type="device" author="AMD" contact="Matthaeus G. Chajdas @anteru" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_36_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_36&quot;"           name="VK_AMD_EXTENSION_36_EXTENSION_NAME"/>
+                <enum value="0"                                         name="VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_negative_viewport_height&quot;"           name="VK_AMD_NEGATIVE_VIEWPORT_HEIGHT_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_37" number="37" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_gpu_shader_half_float" number="37" type="device" author="AMD" contact="Dominik Witczak @dominikwitczak_amd" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_37_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_37&quot;"           name="VK_AMD_EXTENSION_37_EXTENSION_NAME"/>
+                <enum value="1"                                         name="VK_AMD_GPU_SHADER_HALF_FLOAT_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_gpu_shader_half_float&quot;"  name="VK_AMD_GPU_SHADER_HALF_FLOAT_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_AMD_extension_38" number="38" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
+        <extension name="VK_AMD_shader_ballot" number="38" type="device" author="AMD" contact="Dominik Witczak @dominikwitczak_amd" supported="vulkan">
             <require>
-                <enum value="0"                                         name="VK_AMD_EXTENSION_38_SPEC_VERSION"/>
-                <enum value="&quot;VK_AMD_extension_38&quot;"           name="VK_AMD_EXTENSION_38_EXTENSION_NAME"/>
+                <enum value="0"                                         name="VK_AMD_SHADER_BALLOT_SPEC_VERSION"/>
+                <enum value="&quot;VK_AMD_shader_ballot&quot;"          name="VK_AMD_SHADER_BALLOT_EXTENSION_NAME"/>
             </require>
         </extension>
         <extension name="VK_AMD_extension_39" number="39" author="AMD" contact="Daniel Rakos @aqnuep" supported="disabled">
@@ -5693,7 +4700,7 @@
                 <enum value="&quot;VK_NV_extension_54&quot;"            name="VK_NV_EXTENSION_54_EXTENSION_NAME"/>
             </require>
         </extension>
-        <extension name="VK_IMG_format_pvrtc" number="55" author="IMG" contact="Tobias Hector @tobias" supported="vulkan">
+        <extension name="VK_IMG_format_pvrtc" number="55" type="device" author="IMG" contact="Tobias Hector @tobias" supported="vulkan">
             <require>
                 <enum value="1"                                         name="VK_IMG_FORMAT_PVRTC_SPEC_VERSION"/>
                 <enum value="&quot;VK_IMG_format_pvrtc&quot;"           name="VK_IMG_FORMAT_PVRTC_EXTENSION_NAME"/>
@@ -5760,5 +4767,61 @@
                 <enum value="&quot;VK_KHR_extension_61&quot;"           name="VK_KHR_EXTENSION_61_EXTENSION_NAME"/>
             </require>
         </extension>
+        <extension name="VK_EXT_validation_flags" number="62" type="instance" author="Google, Inc." contact="Tobin Ehlis @tobine" supported="vulkan">
+            <require>
+                <enum value="1"                                         name="VK_EXT_VALIDATION_FLAGS_SPEC_VERSION"/>
+                <enum value="&quot;VK_EXT_validation_flags&quot;"           name="VK_EXT_VALIDATION_FLAGS_EXTENSION_NAME"/>
+                <enum offset="0" extends="VkStructureType"              name="VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT"/>
+                <type name="VkValidationFlagsEXT"/>
+            </require>
+        </extension>
+        <extension name="VK_NV_extension_63" number="63" author="NVIDIA" contact="Mathias Heyer @mheyer" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NV_EXTENSION_63_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_extension_63&quot;"            name="VK_NV_EXTENSION_63_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_KHR_extension_64" number="64" author="KHR" contact="Daniel Koch @dgkoch" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_KHR_EXTENSION_64_SPEC_VERSION"/>
+                <enum value="&quot;VK_KHR_extension_64&quot;"           name="VK_KHR_EXTENSION_64_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NV_extension_65" number="65" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NV_EXTENSION_65_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_extension_65&quot;"            name="VK_NV_EXTENSION_65_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_NV_extension_66" number="66" author="NVIDIA" contact="Daniel Koch @dgkoch" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_NV_EXTENSION_66_SPEC_VERSION"/>
+                <enum value="&quot;VK_NV_extension_66&quot;"            name="VK_NV_EXTENSION_66_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_ARM_extension_01" number="67" type="device" author="ARM" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_ARM_EXTENSION_01_SPEC_VERSION"/>
+                <enum value="&quot;VK_ARM_extension_01&quot;"           name="VK_ARM_EXTENSION_01_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_ARM_extension_02" number="68" type="device" author="ARM" contact="Jan-Harald Fredriksen @janharald" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_ARM_EXTENSION_02_SPEC_VERSION"/>
+                <enum value="&quot;VK_ARM_extension_02&quot;"           name="VK_ARM_EXTENSION_02_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_IMG_extension_69" number="69" type="device" author="IMG" contact="Tobias Hector @tobias" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_IMG_EXTENSION_69_SPEC_VERSION"/>
+                <enum value="&quot;VK_IMG_extension_69&quot;"           name="VK_IMG_EXTENSION_69_EXTENSION_NAME"/>
+            </require>
+        </extension>
+        <extension name="VK_KHR_extension_70" number="70" author="KHR" contact="Piers Daniell @pdaniell" supported="disabled">
+            <require>
+                <enum value="0"                                         name="VK_KHR_EXTENSION_70_SPEC_VERSION"/>
+                <enum value="&quot;VK_KHR_extension_70&quot;"           name="VK_KHR_EXTENSION_70_EXTENSION_NAME"/>
+            </require>
+        </extension>
     </extensions>
 </registry>
diff --git a/vk_helper.py b/vk_helper.py
index 5a36fbb..bb0ee82 100755
--- a/vk_helper.py
+++ b/vk_helper.py
@@ -579,6 +579,7 @@
         self.size_helper_gen.setCopyright(self._generateCopyright())
         self.size_helper_gen.setHeader(self._generateSizeHelperHeader())
         self.size_helper_gen.setBody(self._generateSizeHelperFunctions())
+        self.size_helper_gen.setFooter(self._generateSizeHelperFooter())
         self.size_helper_gen.generate()
 
     def generateSizeHelperC(self):
@@ -1482,6 +1483,10 @@
 
     def _generateSizeHelperHeader(self):
         header = []
+        header.append('\n#ifdef __cplusplus\n')
+        header.append('extern "C" {\n')
+        header.append('#endif\n')
+        header.append("\n")
         header.append("//#includes, #defines, globals and such...\n")
         for f in self.include_headers:
             header.append("#include <%s>\n" % f)
@@ -1498,6 +1503,12 @@
         header.append('\n// Function definitions\n')
         return "\n".join(header)
 
+    def _generateSizeHelperFooter(self):
+        footer = []
+        footer.append('\n\n#ifdef __cplusplus')
+        footer.append('}')
+        footer.append('#endif')
+        return "\n".join(footer)
 
     def _generateHeader(self):
         header = []
diff --git a/vk_layer_documentation_generate.py b/vk_layer_documentation_generate.py
index f87091d..7086fb6 100755
--- a/vk_layer_documentation_generate.py
+++ b/vk_layer_documentation_generate.py
@@ -133,7 +133,7 @@
 
 # Class to parse the validation layer test source and store testnames
 class TestParser:
-    def __init__(self, test_file_list, test_group_name=['VkLayerTest', 'VkWsiEnabledLayerTest']):
+    def __init__(self, test_file_list, test_group_name=['VkLayerTest', 'VkPositiveLayerTest', 'VkWsiEnabledLayerTest']):
         self.test_files = test_file_list
         self.tests_set = set()
         self.test_trigger_txt_list = []
diff --git a/vulkan.py b/vulkan.py
index 9628292..752a646 100644
--- a/vulkan.py
+++ b/vulkan.py
@@ -63,9 +63,6 @@
 
         return deref.rstrip()
 
-    def __repr__(self):
-        return "Param(\"%s\", \"%s\")" % (self.ty, self.name)
-
 class Proto(object):
     """A function prototype."""
 
@@ -128,10 +125,6 @@
                 name,
                 ",\n".join(plist))
 
-    def c_typedef(self, suffix="", attr=""):
-        """Return the typedef for the prototype in C."""
-        return self.c_decl(self.name + suffix, attr=attr, typed=True)
-
     def c_func(self, prefix="", attr=""):
         """Return the prototype in C."""
         return self.c_decl(prefix + self.name, attr=attr, typed=False)
@@ -166,29 +159,6 @@
         self.protos = protos
         self.ifdef = ifdef
 
-    def __repr__(self):
-        lines = []
-        lines.append("Extension(")
-        lines.append("    name=\"%s\"," % self.name)
-        lines.append("    headers=[\"%s\"]," %
-                "\", \"".join(self.headers))
-
-        lines.append("    objects=[")
-        for obj in self.objects:
-            lines.append("        \"%s\"," % obj)
-        lines.append("    ],")
-
-        lines.append("    protos=[")
-        for proto in self.protos:
-            param_lines = str(proto).splitlines()
-            param_lines[-1] += ",\n" if proto != self.protos[-1] else ","
-            for p in param_lines:
-                lines.append("        " + p)
-        lines.append("    ],")
-        lines.append(")")
-
-        return "\n".join(lines)
-
 # VK core API
 core = Extension(
     name="VK_CORE",
@@ -1020,7 +990,7 @@
     ],
 )
 
-ext_amd_extension_draw_indirect_count = Extension(
+ext_amd_draw_indirect_count = Extension(
     name="VK_AMD_draw_indirect_count",
     headers=["vulkan/vulkan.h"],
     objects=[],
@@ -1375,7 +1345,7 @@
                          ext_khr_android_surface, ext_khr_display_swapchain]
     extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                              ext_khr_xcb_surface, ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
-                             ext_khr_display, ext_khr_android_surface, ext_amd_extension_draw_indirect_count,
+                             ext_khr_display, ext_khr_android_surface, ext_amd_draw_indirect_count,
                              ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                              ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
 else :
@@ -1384,7 +1354,7 @@
             extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                  ext_khr_display, ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
-                                      ext_khr_display, ext_amd_extension_draw_indirect_count,
+                                      ext_khr_display, ext_amd_draw_indirect_count,
                                       ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                                       ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
         elif sys.platform.startswith('linux') and sys.argv[1] != 'Android':
@@ -1393,28 +1363,28 @@
                                  ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                       ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
-                                      ext_khr_display, ext_amd_extension_draw_indirect_count,
+                                      ext_khr_display, ext_amd_draw_indirect_count,
                                       ext_nv_external_memory_capabilities, ext_khr_display_swapchain,
                                       ext_debug_report, ext_debug_marker]
         else: # android
             extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                  ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
-                                      ext_amd_extension_draw_indirect_count, ext_nv_external_memory_capabilities,
+                                      ext_amd_draw_indirect_count, ext_nv_external_memory_capabilities,
                                       ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
     else :
         if sys.argv[1] == 'Win32' or sys.argv[1] == 'msys':
             extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
                                  ext_khr_display, ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_win32_surface,
-                                      ext_khr_display, ext_amd_extension_draw_indirect_count,
+                                      ext_khr_display, ext_amd_draw_indirect_count,
                                       ext_nv_external_memory_capabilities, ext_nv_external_memory_win32,
                                       ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
         elif sys.argv[1] == 'Android':
             extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
                                  ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_android_surface,
-                                      ext_amd_extension_draw_indirect_count, ext_nv_external_memory_capabilities,
+                                      ext_amd_draw_indirect_count, ext_nv_external_memory_capabilities,
                                       ext_khr_display_swapchain, ext_debug_report, ext_debug_marker]
         elif sys.argv[1] == 'Xcb' or sys.argv[1] == 'Xlib' or sys.argv[1] == 'Wayland' or sys.argv[1] == 'Mir' or sys.argv[1] == 'Display':
             extensions = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
@@ -1422,7 +1392,7 @@
                                  ext_khr_display, ext_khr_display_swapchain]
             extensions_all = [core, ext_khr_surface, ext_khr_device_swapchain, ext_khr_xcb_surface,
                                       ext_khr_xlib_surface, ext_khr_wayland_surface, ext_khr_mir_surface,
-                                      ext_khr_display, ext_amd_extension_draw_indirect_count,
+                                      ext_khr_display, ext_amd_draw_indirect_count,
                                       ext_nv_external_memory_capabilities, ext_khr_display_swapchain,
                                       ext_debug_report, ext_debug_marker]
         else:
@@ -1487,69 +1457,3 @@
     protos_all.extend(ext.protos)
 
 proto_all_names = [proto.name for proto in protos_all]
-
-def parse_vk_h(filename):
-    # read object and protoype typedefs
-    object_lines = []
-    proto_lines = []
-    with open(filename, "r") as fp:
-        for line in fp:
-            line = line.strip()
-            if line.startswith("VK_DEFINE"):
-                begin = line.find("(") + 1
-                end = line.find(",")
-                # extract the object type
-                object_lines.append(line[begin:end])
-            if line.startswith("typedef") and line.endswith(");"):
-                if "*PFN_vkVoidFunction" in line:
-                    continue
-
-                # drop leading "typedef " and trailing ");"
-                proto_lines.append(line[8:-2])
-
-    # parse proto_lines to protos
-    protos = []
-    for line in proto_lines:
-        first, rest = line.split(" (VKAPI_PTR *PFN_vk")
-        second, third = rest.split(")(")
-
-        # get the return type, no space before "*"
-        proto_ret = "*".join([t.rstrip() for t in first.split("*")])
-
-        # get the name
-        proto_name = second.strip()
-
-        # get the list of params
-        param_strs = third.split(", ")
-        params = []
-        for s in param_strs:
-            ty, name = s.rsplit(" ", 1)
-
-            # no space before "*"
-            ty = "*".join([t.rstrip() for t in ty.split("*")])
-            # attach [] to ty
-            idx = name.rfind("[")
-            if idx >= 0:
-                ty += name[idx:]
-                name = name[:idx]
-
-            params.append(Param(ty, name))
-
-        protos.append(Proto(proto_ret, proto_name, params))
-
-    # make them an extension and print
-    ext = Extension("VK_CORE",
-            headers=["vulkan/vulkan.h"],
-            objects=object_lines,
-            protos=protos)
-    print("core =", str(ext))
-
-    print("")
-    print("typedef struct VkLayerDispatchTable_")
-    print("{")
-    for proto in ext.protos:
-        print("    PFN_vk%s %s;" % (proto.name, proto.name))
-    print("} VkLayerDispatchTable;")
-
-if __name__ == "__main__":
-    parse_vk_h("include/vulkan/vulkan.h")