Add basic support for Vulkan 1.2: SPV_ENV_VULKAN_1_2
diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h
index 5dcb81a..e14e2e7 100644
--- a/include/spirv-tools/libspirv.h
+++ b/include/spirv-tools/libspirv.h
@@ -450,6 +450,7 @@
   SPV_ENV_UNIVERSAL_1_4,  // SPIR-V 1.4 latest revision, no other restrictions.
   SPV_ENV_VULKAN_1_1_SPIRV_1_4,  // Vulkan 1.1 with SPIR-V 1.4 binary.
   SPV_ENV_UNIVERSAL_1_5,  // SPIR-V 1.5 latest revision, no other restrictions.
+  SPV_ENV_VULKAN_1_2,     // Vulkan 1.2 latest revision.
 } spv_target_env;
 
 // SPIR-V Validator can be parameterized with the following Universal Limits.
diff --git a/source/ext_inst.cpp b/source/ext_inst.cpp
index e332f0d..53ebb3c 100644
--- a/source/ext_inst.cpp
+++ b/source/ext_inst.cpp
@@ -88,6 +88,7 @@
     case SPV_ENV_WEBGPU_0:
     case SPV_ENV_UNIVERSAL_1_4:
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       *pExtInstTable = &kTable_1_0;
       return SPV_SUCCESS;
     default:
diff --git a/source/spirv_target_env.cpp b/source/spirv_target_env.cpp
index 86f2c8d..c4730e8 100644
--- a/source/spirv_target_env.cpp
+++ b/source/spirv_target_env.cpp
@@ -68,6 +68,8 @@
       return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
     case SPV_ENV_UNIVERSAL_1_5:
       return "SPIR-V 1.5";
+    case SPV_ENV_VULKAN_1_2:
+      return "SPIR-V 1.5 (under Vulkan 1.2 semantics)";
   }
   return "";
 }
@@ -102,6 +104,7 @@
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
       return SPV_SPIRV_VERSION_WORD(1, 4);
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       return SPV_SPIRV_VERSION_WORD(1, 5);
   }
   return SPV_SPIRV_VERSION_WORD(0, 0);
@@ -111,6 +114,7 @@
     {"vulkan1.1spv1.4", SPV_ENV_VULKAN_1_1_SPIRV_1_4},
     {"vulkan1.0", SPV_ENV_VULKAN_1_0},
     {"vulkan1.1", SPV_ENV_VULKAN_1_1},
+    {"vulkan1.2", SPV_ENV_VULKAN_1_2},
     {"spv1.0", SPV_ENV_UNIVERSAL_1_0},
     {"spv1.1", SPV_ENV_UNIVERSAL_1_1},
     {"spv1.2", SPV_ENV_UNIVERSAL_1_2},
@@ -175,6 +179,7 @@
     case SPV_ENV_VULKAN_1_0:
     case SPV_ENV_VULKAN_1_1:
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
+    case SPV_ENV_VULKAN_1_2:
       return true;
   }
   return false;
@@ -197,6 +202,7 @@
     case SPV_ENV_UNIVERSAL_1_4:
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       return false;
     case SPV_ENV_OPENCL_1_2:
     case SPV_ENV_OPENCL_EMBEDDED_1_2:
@@ -235,6 +241,7 @@
     case SPV_ENV_UNIVERSAL_1_4:
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       return false;
     case SPV_ENV_WEBGPU_0:
       return true;
@@ -262,6 +269,7 @@
     case SPV_ENV_UNIVERSAL_1_4:
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       return false;
     case SPV_ENV_OPENGL_4_0:
     case SPV_ENV_OPENGL_4_1:
@@ -299,7 +307,8 @@
     case SPV_ENV_VULKAN_1_0:
     case SPV_ENV_VULKAN_1_1:
     case SPV_ENV_VULKAN_1_1_SPIRV_1_4: {
-      return "Vulkan";
+      case SPV_ENV_VULKAN_1_2:
+        return "Vulkan";
     }
     case SPV_ENV_WEBGPU_0: {
       return "WebGPU";
diff --git a/source/table.cpp b/source/table.cpp
index b7a96cc..8340e8e 100644
--- a/source/table.cpp
+++ b/source/table.cpp
@@ -41,6 +41,7 @@
     case SPV_ENV_WEBGPU_0:
     case SPV_ENV_UNIVERSAL_1_4:
     case SPV_ENV_UNIVERSAL_1_5:
+    case SPV_ENV_VULKAN_1_2:
       break;
     default:
       return nullptr;
diff --git a/source/val/validate_capability.cpp b/source/val/validate_capability.cpp
index ad6cb26..fcf7846 100644
--- a/source/val/validate_capability.cpp
+++ b/source/val/validate_capability.cpp
@@ -55,6 +55,12 @@
   return false;
 }
 
+bool IsSupportGuaranteedVulkan_1_2(uint32_t capability) {
+  if (IsSupportGuaranteedVulkan_1_1(capability)) return true;
+  // TODO(dneto): Check if any additional capability is required.
+  return false;
+}
+
 bool IsSupportOptionalVulkan_1_0(uint32_t capability) {
   switch (capability) {
     case SpvCapabilityGeometry:
@@ -121,6 +127,12 @@
   return false;
 }
 
+bool IsSupportOptionalVulkan_1_2(uint32_t capability) {
+  if (IsSupportOptionalVulkan_1_1(capability)) return true;
+  // TODO(dneto): Check which additional capability is optional.
+  return false;
+}
+
 bool IsSupportGuaranteedOpenCL_1_2(uint32_t capability, bool embedded_profile) {
   switch (capability) {
     case SpvCapabilityAddresses:
@@ -284,6 +296,15 @@
              << " is not allowed by Vulkan 1.1 specification"
              << " (or requires extension)";
     }
+  } else if (env == SPV_ENV_VULKAN_1_2) {
+    if (!IsSupportGuaranteedVulkan_1_2(capability) &&
+        !IsSupportOptionalVulkan_1_2(capability) &&
+        !IsEnabledByExtension(_, capability)) {
+      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
+             << "Capability " << capability_str()
+             << " is not allowed by Vulkan 1.2 specification"
+             << " (or requires extension)";
+    }
   } else if (env == SPV_ENV_OPENCL_1_2 || env == SPV_ENV_OPENCL_EMBEDDED_1_2) {
     if (!IsSupportGuaranteedOpenCL_1_2(capability, opencl_embedded) &&
         !IsSupportOptionalOpenCL_1_2(capability) &&
diff --git a/source/val/validate_scopes.cpp b/source/val/validate_scopes.cpp
index 1b98786..320d828 100644
--- a/source/val/validate_scopes.cpp
+++ b/source/val/validate_scopes.cpp
@@ -212,13 +212,14 @@
              << "Device, Workgroup and Invocation";
     }
     // Vulkan 1.1 specifc rules
-    if (_.context()->target_env == SPV_ENV_VULKAN_1_1 &&
+    if ((_.context()->target_env == SPV_ENV_VULKAN_1_1 ||
+         _.context()->target_env == SPV_ENV_VULKAN_1_2) &&
         value != SpvScopeDevice && value != SpvScopeWorkgroup &&
         value != SpvScopeSubgroup && value != SpvScopeInvocation) {
       return _.diag(SPV_ERROR_INVALID_DATA, inst)
              << spvOpcodeString(opcode)
-             << ": in Vulkan 1.1 environment Memory Scope is limited to "
-             << "Device, Workgroup and Invocation";
+             << ": in Vulkan 1.1 and 1.2 environment Memory Scope is limited "
+             << "to Device, Workgroup and Invocation";
     }
   }
 
diff --git a/test/target_env_test.cpp b/test/target_env_test.cpp
index 9f80e83..5dc7415 100644
--- a/test/target_env_test.cpp
+++ b/test/target_env_test.cpp
@@ -79,6 +79,7 @@
         {"spv1.3", true, SPV_ENV_UNIVERSAL_1_3},
         {"vulkan1.0", true, SPV_ENV_VULKAN_1_0},
         {"vulkan1.1", true, SPV_ENV_VULKAN_1_1},
+        {"vulkan1.2", true, SPV_ENV_VULKAN_1_2},
         {"opencl2.1", true, SPV_ENV_OPENCL_2_1},
         {"opencl2.2", true, SPV_ENV_OPENCL_2_2},
         {"opengl4.0", true, SPV_ENV_OPENGL_4_0},
@@ -95,7 +96,7 @@
         {"webgpu0", true, SPV_ENV_WEBGPU_0},
         {"opencl2.3", false, SPV_ENV_UNIVERSAL_1_0},
         {"opencl3.0", false, SPV_ENV_UNIVERSAL_1_0},
-        {"vulkan1.2", false, SPV_ENV_UNIVERSAL_1_0},
+        {"vulkan1.9", false, SPV_ENV_UNIVERSAL_1_0},
         {"vulkan2.0", false, SPV_ENV_UNIVERSAL_1_0},
         {nullptr, false, SPV_ENV_UNIVERSAL_1_0},
         {"", false, SPV_ENV_UNIVERSAL_1_0},