Merge remote-tracking branch 'remotes/upstream/master' into main

Bug: 112606
Change-Id: I0bb9f721b797e5c00c29e9d3d16eeaf9eb0bdbc5
diff --git a/BUILD.gn b/BUILD.gn
index b213210..9b81845 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -15,10 +15,6 @@
 
 import("//build_overrides/vulkan_validation_layers.gni")
 
-# Fuchsia has non-upstream changes to the vulkan layers, so we don't want
-# to build it from upstream sources.
-assert(!is_fuchsia)
-
 vulkan_undefine_configs = []
 if (is_win) {
   vulkan_undefine_configs += [ "//build/config/win:unicode" ]
@@ -47,6 +43,19 @@
   ]
 }
 
+config("generated_layers_config") {
+  cflags = [
+    "-Wno-conversion",
+    "-Wno-deprecated-copy",
+    "-Wno-extra-semi",
+    "-Wno-implicit-fallthrough",
+    "-Wno-missing-field-initializers",
+    "-Wno-newline-eof",
+    "-Wno-sign-compare",
+    "-Wno-unused-const-variable",
+  ]
+}
+
 config("vulkan_internal_config") {
   defines = [
     "VULKAN_NON_CMAKE_BUILD",
@@ -67,6 +76,12 @@
       "FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
     ]
   }
+
+  # Suppress warnings the vulkan code doesn't comply with.
+  if (is_fuchsia) {
+    configs = [ "//build/config:Wno-unused-but-set-variable" ]
+  }
+  cflags += [ "-Wno-extra-semi" ]
 }
 
 # The validation layers
@@ -77,6 +92,7 @@
     "layers",
     "layers/generated",
   ]
+  cflags = [ "-Wno-extra-semi" ]
 }
 
 core_validation_sources = [
@@ -223,11 +239,12 @@
   action("vulkan_gen_json_files") {
     script = "build-gn/generate_vulkan_layers_json.py"
 
-    # Make sure that the cleanup of old layer JSON files happens before the new ones are generated.
-    deps = [
-      ":vulkan_clean_old_validation_layer_objects",
-      "$vulkan_headers_dir:vulkan_headers",
-    ]
+    deps = [ "$vulkan_headers_dir:vulkan_headers" ]
+    if (!is_fuchsia) {
+      # Make sure that the cleanup of old layer JSON files happens before the new ones are generated.
+      deps += [ ":vulkan_clean_old_validation_layer_objects" ]
+    }
+
     json_names = [ "VkLayer_khronos_validation.json" ]
     sources = [ "$vulkan_headers_dir/include/vulkan/vulkan_core.h" ]
     outputs = []
@@ -242,6 +259,8 @@
       _platform = "Windows"
     } else if (is_mac) {
       _platform = "Darwin"
+    } else if (is_fuchsia) {
+      _platform = "Fuchsia"
     } else {
       _platform = "Other"
     }
@@ -252,6 +271,9 @@
              rebase_path("layers/json", root_build_dir),
              rebase_path(vulkan_data_dir, root_build_dir),
            ] + rebase_path(sources, root_build_dir)
+    if (is_fuchsia) {
+      args += [ "--no-path-prefix" ]
+    }
 
     # The layer JSON files are part of the necessary data deps.
     data = outputs
@@ -303,10 +325,13 @@
     ":vulkan_internal_config",
     ":vulkan_memory_allocator_config",
   ]
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
   public_deps = [ "$vulkan_headers_dir:vulkan_headers" ]
+
   configs -= vulkan_undefine_configs
+  if (!is_fuchsia) {
+    configs -= [ "//build/config/compiler:chromium_code" ]
+    configs += [ "//build/config/compiler:no_chromium_code" ]
+  }
 }
 
 config("vulkan_core_validation_config") {
@@ -331,20 +356,36 @@
   }
 }
 
+if (is_fuchsia) {
+  library_type = "loadable_module"
+} else {
+  library_type = "shared_library"
+}
+
 foreach(layer_info, layers) {
   name = layer_info[0]
-  shared_library("VkLayer_$name") {
+  target(library_type, "VkLayer_$name") {
     defines = []
-    configs -= [ "//build/config/compiler:chromium_code" ]
-    configs += [ "//build/config/compiler:no_chromium_code" ]
-    configs += [ "//build/config/compiler:rtti" ]
+    ldflags = []
+    if (is_fuchsia) {
+      configs -= [ "//build/config:thread_safety_annotations" ]
+      ldflags += [ "-static-libstdc++" ]
+      configs += [ "//build/config:rtti" ]
+    } else {
+      configs -= [ "//build/config/compiler:chromium_code" ]
+      configs += [ "//build/config/compiler:no_chromium_code" ]
+      configs += [ "//build/config/compiler:rtti" ]
+    }
     configs -= vulkan_undefine_configs
+    configs += [ ":generated_layers_config" ]
     public_configs = [ ":vulkan_layer_config" ]
-    deps = [
-      # Make sure the cleanup of old layers happen before the new ones are compiled.
-      ":vulkan_clean_old_validation_layer_objects",
-      ":vulkan_layer_utils",
-    ]
+    deps = [ ":vulkan_layer_utils" ]
+    if (!is_fuchsia) {
+      deps += [
+        # Make sure the cleanup of old layers happen before the new ones are compiled.
+        ":vulkan_clean_old_validation_layer_objects",
+      ]
+    }
     if (layer_info[2] != "") {
       deps += layer_info[2]
     }
@@ -353,10 +394,10 @@
       defines += [ "NOMINMAX" ]
       sources += [ "layers/VkLayer_$name.def" ]
     }
-    if (is_linux || is_android) {
-      ldflags = [ "-Wl,-Bsymbolic,--exclude-libs,ALL" ]
+    if (is_linux || is_android || is_fuchsia) {
+      ldflags += [ "-Wl,-Bsymbolic,--exclude-libs,ALL" ]
     }
-    if (ozone_platform_x11) {
+    if (defined(ozone_platform_x11) && ozone_platform_x11) {
       defines += [ "VK_USE_PLATFORM_XLIB_KHR" ]
     }
     if (is_android) {
@@ -371,9 +412,18 @@
 }
 
 group("vulkan_validation_layers") {
+  public_deps = []
   data_deps = []
   foreach(layer_info, layers) {
     name = layer_info[0]
-    data_deps += [ ":VkLayer_$name" ]
+    if (is_fuchsia) {
+      public_deps += [ ":VkLayer_$name" ]
+    } else {
+      data_deps += [ ":VkLayer_$name" ]
+    }
   }
 }
+
+group("tests") {
+  # TODO(fxbug.dev/13288)
+}
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..8089867
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,4 @@
+reveman@google.com
+jbauman@google.com
+rosasco@google.com
+cstout@google.com
diff --git a/README.fuchsia b/README.fuchsia
new file mode 100644
index 0000000..17b1759
--- /dev/null
+++ b/README.fuchsia
@@ -0,0 +1,8 @@
+Name: Vulkan-ValidationLayers
+License: Apache 2.0
+License File: LICENSE.txt
+Upstream Git: https://github.com/KhronosGroup/Vulkan-ValidationLayers
+Description:
+
+Provides the Khronos official Vulkan validation layers.
+
diff --git a/build-gn/commit_id.py b/build-gn/commit_id.py
index 78e978e..16af01a 100755
--- a/build-gn/commit_id.py
+++ b/build-gn/commit_id.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2.7
 
 # Copyright (C) 2018 The ANGLE Project Authors.
 #
diff --git a/build-gn/generate_vulkan_layers_json.py b/build-gn/generate_vulkan_layers_json.py
index e744745..076ef21 100755
--- a/build-gn/generate_vulkan_layers_json.py
+++ b/build-gn/generate_vulkan_layers_json.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python2.7
 
 # Copyright (C) 2016 The ANGLE Project Authors.
 #
@@ -35,9 +35,10 @@
 def main():
     parser = argparse.ArgumentParser(description=__doc__)
     parser.add_argument('--icd', action='store_true')
+    parser.add_argument('--no-path-prefix', action='store_true')
     parser.add_argument('--platform', type=str, default=platform.system(),
         help='Target platform to build validation layers for: '
-             'Linux|Darwin|Windows|...')
+             'Linux|Darwin|Windows|Fuchsia|...')
     parser.add_argument('source_dir')
     parser.add_argument('target_dir')
     parser.add_argument('version_header', help='path to vulkan_core.h')
@@ -98,10 +99,14 @@
         return 1
 
     # Set json file prefix and suffix for generating files, default to Linux.
-    relative_path_prefix = '../lib'
+    if args.no_path_prefix:
+        relative_path_prefix = ''
+    elif args.platform == 'Windows':
+        relative_path_prefix = r'..\\'  # json-escaped, hence two backslashes.
+    else:
+        relative_path_prefix = '../lib'
     file_type_suffix = '.so'
     if args.platform == 'Windows':
-        relative_path_prefix = r'..\\'  # json-escaped, hence two backslashes.
         file_type_suffix = '.dll'
     elif args.platform == 'Darwin':
         file_type_suffix = '.dylib'
diff --git a/build-gn/layers-fuchsia.gni b/build-gn/layers-fuchsia.gni
new file mode 100644
index 0000000..ee95b2f
--- /dev/null
+++ b/build-gn/layers-fuchsia.gni
@@ -0,0 +1,74 @@
+# Copyright 2018 The Fuchsia Authors
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+# This scope makes it easy to incorporate the Vulkan validation layers into a
+# package that is part of the Fuchsia system build.
+#
+# To use it, import this gni file and add the entries of the
+# 'vulkan_validation_layers' scope to the package's 'loadable_modules',
+# 'resources', and 'public_deps' parameters.
+#
+# Example BUILD.gn file:
+#
+# import("//src/graphics/lib/vulkan/layers.gni")
+#
+# package("my_funky_vulkan_using_program") {
+#   loadable_modules = [
+#     ...
+#     ] + vulkan_validation_layers.loadable_modules
+#
+#   resources = [
+#     ...
+#     ] + vulkan_validation_layers.resources
+#
+#   public_deps = [
+#     ...
+#     ] + vulkan_validation_layers.public_deps
+# }
+#
+# This will end up placing the validation libraries within the package's "lib/"
+# directory, where they can be loaded like normal libraries, and place the layer
+# configuration data in the package's "data/vulkan/explicit_layer.d" directory which
+# is mapped to "/config/vulkan/explicit_layer.d"
+
+import("//build_overrides/vulkan_validation_layers.gni")
+
+vulkan_data_dir = "$root_out_dir/$vulkan_data_subdir"
+
+vulkan_validation_layers = {
+  loadable_modules = [
+    {
+      name = "VkLayer_khronos_validation.so"
+    },
+  ]
+
+  resources = [
+    {
+      path = rebase_path("$vulkan_data_dir/VkLayer_khronos_validation.json")
+      dest = "vulkan/explicit_layer.d/VkLayer_khronos_validation.json"
+    },
+  ]
+
+  public_deps = [
+    "//third_party/Vulkan-ValidationLayers:vulkan_gen_json_files",
+    "//third_party/Vulkan-ValidationLayers:vulkan_validation_layers",
+  ]
+}
diff --git a/build-gn/remove_files.py b/build-gn/remove_files.py
index 7095913..ba30527 100755
--- a/build-gn/remove_files.py
+++ b/build-gn/remove_files.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/env python2.7
 
 # Copyright (C) 2019 The ANGLE Project Authors.
 #
diff --git a/layers/core_validation.cpp b/layers/core_validation.cpp
index 2f2c9cf..5e32cb3 100644
--- a/layers/core_validation.cpp
+++ b/layers/core_validation.cpp
@@ -17849,8 +17849,19 @@
 
 #ifdef VK_USE_PLATFORM_FUCHSIA
 bool CoreChecks::PreCallValidateImportSemaphoreZirconHandleFUCHSIA(
-    VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA *pImportSemaphoreZirconHandleInfo) const {
-    return ValidateImportSemaphore(pImportSemaphoreZirconHandleInfo->semaphore, "vkImportSemaphoreZirconHandleFUCHSIA");
+    VkDevice device, const VkImportSemaphoreZirconHandleInfoFUCHSIA *info) const {
+    bool skip = false;
+    const char *func_name = "vkImportSemaphoreZirconHandleFUCHSIA";
+    auto sem_state = Get<SEMAPHORE_STATE>(info->semaphore);
+    if (sem_state) {
+        skip |= ValidateObjectNotInUse(sem_state.get(), func_name, kVUIDUndefined);
+
+        if (sem_state->type == VK_SEMAPHORE_TYPE_TIMELINE) {
+            skip |= LogError(sem_state->Handle(), "VUID-VkImportSemaphoreZirconHandleInfoFUCHSIA-semaphoreType-04768",
+                             "%s(): VkSemaphoreTypeCreateInfo::semaphoreType field must not be VK_SEMAPHORE_TYPE_TIMELINE", func_name);
+        }
+    }
+    return skip;
 }
 
 void CoreChecks::PostCallRecordImportSemaphoreZirconHandleFUCHSIA(
diff --git a/layers/generated/spirv_grammar_helper.cpp b/layers/generated/spirv_grammar_helper.cpp
index 33d371c..50585f7 100644
--- a/layers/generated/spirv_grammar_helper.cpp
+++ b/layers/generated/spirv_grammar_helper.cpp
@@ -333,7 +333,6 @@
     {spv::OpSubgroupAllKHR, {"OpSubgroupAllKHR", true, true, 0, 0, 0}},
     {spv::OpSubgroupAnyKHR, {"OpSubgroupAnyKHR", true, true, 0, 0, 0}},
     {spv::OpSubgroupAllEqualKHR, {"OpSubgroupAllEqualKHR", true, true, 0, 0, 0}},
-    {spv::OpGroupNonUniformRotateKHR, {"OpGroupNonUniformRotateKHR", true, true, 0, 3, 0}},
     {spv::OpSubgroupReadInvocationKHR, {"OpSubgroupReadInvocationKHR", true, true, 0, 0, 0}},
     {spv::OpTraceRayKHR, {"OpTraceRayKHR", false, false, 0, 0, 0}},
     {spv::OpExecuteCallableKHR, {"OpExecuteCallableKHR", false, false, 0, 0, 0}},
@@ -365,8 +364,6 @@
     {spv::OpFragmentFetchAMD, {"OpFragmentFetchAMD", true, true, 0, 0, 0}},
     {spv::OpReadClockKHR, {"OpReadClockKHR", true, true, 0, 3, 0}},
     {spv::OpImageSampleFootprintNV, {"OpImageSampleFootprintNV", true, true, 0, 0, 7}},
-    {spv::OpEmitMeshTasksEXT, {"OpEmitMeshTasksEXT", false, false, 0, 0, 0}},
-    {spv::OpSetMeshOutputsEXT, {"OpSetMeshOutputsEXT", false, false, 0, 0, 0}},
     {spv::OpGroupNonUniformPartitionNV, {"OpGroupNonUniformPartitionNV", true, true, 0, 0, 0}},
     {spv::OpWritePackedPrimitiveIndices4x8NV, {"OpWritePackedPrimitiveIndices4x8NV", false, false, 0, 0, 0}},
     {spv::OpReportIntersectionKHR, {"OpReportIntersectionKHR", true, true, 0, 0, 0}},
@@ -432,9 +429,6 @@
     {spv::OpSaveMemoryINTEL, {"OpSaveMemoryINTEL", true, true, 0, 0, 0}},
     {spv::OpRestoreMemoryINTEL, {"OpRestoreMemoryINTEL", false, false, 0, 0, 0}},
     {spv::OpLoopControlINTEL, {"OpLoopControlINTEL", false, false, 0, 0, 0}},
-    {spv::OpAliasDomainDeclINTEL, {"OpAliasDomainDeclINTEL", false, true, 0, 0, 0}},
-    {spv::OpAliasScopeDeclINTEL, {"OpAliasScopeDeclINTEL", false, true, 0, 0, 0}},
-    {spv::OpAliasScopeListDeclINTEL, {"OpAliasScopeListDeclINTEL", false, true, 0, 0, 0}},
     {spv::OpPtrCastToCrossWorkgroupINTEL, {"OpPtrCastToCrossWorkgroupINTEL", true, true, 0, 0, 0}},
     {spv::OpCrossWorkgroupCastToPtrINTEL, {"OpCrossWorkgroupCastToPtrINTEL", true, true, 0, 0, 0}},
     {spv::OpReadPipeBlockingINTEL, {"OpReadPipeBlockingINTEL", true, true, 0, 0, 0}},
@@ -462,16 +456,6 @@
     {spv::OpTypeStructContinuedINTEL, {"OpTypeStructContinuedINTEL", false, false, 0, 0, 0}},
     {spv::OpConstantCompositeContinuedINTEL, {"OpConstantCompositeContinuedINTEL", false, false, 0, 0, 0}},
     {spv::OpSpecConstantCompositeContinuedINTEL, {"OpSpecConstantCompositeContinuedINTEL", false, false, 0, 0, 0}},
-    {spv::OpControlBarrierArriveINTEL, {"OpControlBarrierArriveINTEL", false, false, 2, 1, 0}},
-    {spv::OpControlBarrierWaitINTEL, {"OpControlBarrierWaitINTEL", false, false, 2, 1, 0}},
-    {spv::OpGroupIMulKHR, {"OpGroupIMulKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupFMulKHR, {"OpGroupFMulKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupBitwiseAndKHR, {"OpGroupBitwiseAndKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupBitwiseOrKHR, {"OpGroupBitwiseOrKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupBitwiseXorKHR, {"OpGroupBitwiseXorKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupLogicalAndKHR, {"OpGroupLogicalAndKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupLogicalOrKHR, {"OpGroupLogicalOrKHR", true, true, 0, 3, 0}},
-    {spv::OpGroupLogicalXorKHR, {"OpGroupLogicalXorKHR", true, true, 0, 3, 0}},
 };
 // clang-format on
 
@@ -661,7 +645,6 @@
         case spv::ImageOperandsVolatileTexelMask:
         case spv::ImageOperandsSignExtendMask:
         case spv::ImageOperandsZeroExtendMask:
-        case spv::ImageOperandsNontemporalMask:
             return 0;
         case spv::ImageOperandsBiasMask:
         case spv::ImageOperandsLodMask:
@@ -735,8 +718,6 @@
             return "ShaderRecordBufferNV";
         case spv::StorageClassPhysicalStorageBuffer:
             return "PhysicalStorageBuffer";
-        case spv::StorageClassTaskPayloadWorkgroupEXT:
-            return "TaskPayloadWorkgroupEXT";
         case spv::StorageClassCodeSectionINTEL:
             return "CodeSectionINTEL";
         case spv::StorageClassDeviceOnlyINTEL:
@@ -780,10 +761,6 @@
             return "MissNV";
         case spv::ExecutionModelCallableNV:
             return "CallableNV";
-        case spv::ExecutionModelTaskEXT:
-            return "TaskEXT";
-        case spv::ExecutionModelMeshEXT:
-            return "MeshEXT";
         default:
             return "unknown";
     }
diff --git a/layers/parameter_validation_utils.cpp b/layers/parameter_validation_utils.cpp
index d8395cd..ca0c622 100644
--- a/layers/parameter_validation_utils.cpp
+++ b/layers/parameter_validation_utils.cpp
@@ -373,6 +373,7 @@
         tmp_features2_state.features = {};
     }
     // Use pCreateInfo->pNext to get full chain
+    FreePnextChain(stateless_validation->device_createinfo_pnext);
     stateless_validation->device_createinfo_pnext = SafePnextCopy(pCreateInfo->pNext);
     stateless_validation->physical_device_features2 = tmp_features2_state;
 }
diff --git a/layers/state_tracker.cpp b/layers/state_tracker.cpp
index b9d11c9..c68aeca 100644
--- a/layers/state_tracker.cpp
+++ b/layers/state_tracker.cpp
@@ -3854,6 +3854,16 @@
 }
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
 
+#ifdef VK_USE_PLATFORM_FUCHSIA
+void ValidationStateTracker::PostCallRecordCreateImagePipeSurfaceFUCHSIA(VkInstance instance,
+                                                                         const VkImagePipeSurfaceCreateInfoFUCHSIA *pCreateInfo,
+                                                                         const VkAllocationCallbacks *pAllocator,
+                                                                         VkSurfaceKHR *pSurface, VkResult result) {
+    if (VK_SUCCESS != result) return;
+    RecordVulkanSurface(pSurface);
+}
+#endif  // VK_USE_PLATFORM_FUCHSIA
+
 #ifdef VK_USE_PLATFORM_IOS_MVK
 void ValidationStateTracker::PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK *pCreateInfo,
                                                                const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface,
diff --git a/layers/state_tracker.h b/layers/state_tracker.h
index 1a8d162..356cc46 100644
--- a/layers/state_tracker.h
+++ b/layers/state_tracker.h
@@ -1168,6 +1168,11 @@
                                                const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface,
                                                VkResult result) override;
 #endif  // VK_USE_PLATFORM_ANDROID_KHR
+#ifdef VK_USE_PLATFORM_FUCHSIA
+    void PostCallRecordCreateImagePipeSurfaceFUCHSIA(VkInstance instance, const VkImagePipeSurfaceCreateInfoFUCHSIA* pCreateInfo,
+                                                     const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface,
+                                                     VkResult result) override;
+#endif  // VK_USE_PLATFORM_FUCHSIA
 #ifdef VK_USE_PLATFORM_IOS_MVK
     void PostCallRecordCreateIOSSurfaceMVK(VkInstance instance, const VkIOSSurfaceCreateInfoMVK* pCreateInfo,
                                            const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface,