Implement tool changes for SPV_EXT_mesh_shader. (#4915)

- Added validation rule to support EXT_mesh_shader from SPIRV 1.4 onwards
diff --git a/DEPS b/DEPS
index 78c9dd3..e0b4c55 100644
--- a/DEPS
+++ b/DEPS
@@ -6,7 +6,7 @@
   'effcee_revision': 'ddf5e2bb92957dc8a12c5392f8495333d6844133',
   'googletest_revision': '548b13dc3c02b93f60eeff9a0cc6e11c1ea722ca',
   're2_revision': '5723bb8950318135ed9cf4fc76bed988a087f536',
-  'spirv_headers_revision': 'b2a156e1c0434bc8c99aaebba1c7be98be7ac580',
+  'spirv_headers_revision': '87d5b782bec60822aa878941e6b13c0a9a954c9b',
 }
 
 deps = {
diff --git a/source/opt/instrument_pass.cpp b/source/opt/instrument_pass.cpp
index 3d48b32..d143d59 100644
--- a/source/opt/instrument_pass.cpp
+++ b/source/opt/instrument_pass.cpp
@@ -245,7 +245,9 @@
     } break;
     case SpvExecutionModelGLCompute:
     case SpvExecutionModelTaskNV:
-    case SpvExecutionModelMeshNV: {
+    case SpvExecutionModelMeshNV:
+    case SpvExecutionModelTaskEXT:
+    case SpvExecutionModelMeshEXT: {
       // Load and store GlobalInvocationId.
       uint32_t load_id = GenVarLoad(
           context()->GetBuiltinInputVarId(SpvBuiltInGlobalInvocationId),
@@ -1064,7 +1066,8 @@
       stage != SpvExecutionModelAnyHitNV &&
       stage != SpvExecutionModelClosestHitNV &&
       stage != SpvExecutionModelMissNV &&
-      stage != SpvExecutionModelCallableNV) {
+      stage != SpvExecutionModelCallableNV &&
+      stage != SpvExecutionModelTaskEXT && stage != SpvExecutionModelMeshEXT) {
     if (consumer()) {
       std::string message = "Stage not supported by instrumentation";
       consumer()(SPV_MSG_ERROR, 0, {0, 0, 0}, message.c_str());
diff --git a/source/val/validate_atomics.cpp b/source/val/validate_atomics.cpp
index 3b0a7fa..bf565c3 100644
--- a/source/val/validate_atomics.cpp
+++ b/source/val/validate_atomics.cpp
@@ -40,6 +40,7 @@
     case SpvStorageClassImage:
     case SpvStorageClassFunction:
     case SpvStorageClassPhysicalStorageBuffer:
+    case SpvStorageClassTaskPayloadWorkgroupEXT:
       return true;
       break;
     default:
@@ -206,12 +207,13 @@
               (storage_class != SpvStorageClassStorageBuffer) &&
               (storage_class != SpvStorageClassWorkgroup) &&
               (storage_class != SpvStorageClassImage) &&
-              (storage_class != SpvStorageClassPhysicalStorageBuffer)) {
+              (storage_class != SpvStorageClassPhysicalStorageBuffer) &&
+              (storage_class != SpvStorageClassTaskPayloadWorkgroupEXT)) {
             return _.diag(SPV_ERROR_INVALID_DATA, inst)
                    << _.VkErrorID(4686) << spvOpcodeString(opcode)
                    << ": Vulkan spec only allows storage classes for atomic to "
-                      "be: Uniform, Workgroup, Image, StorageBuffer, or "
-                      "PhysicalStorageBuffer.";
+                      "be: Uniform, Workgroup, Image, StorageBuffer, "
+                      "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT.";
           }
         } else if (storage_class == SpvStorageClassFunction) {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
diff --git a/source/val/validate_barriers.cpp b/source/val/validate_barriers.cpp
index 3a9e3e7..03225d8 100644
--- a/source/val/validate_barriers.cpp
+++ b/source/val/validate_barriers.cpp
@@ -50,7 +50,8 @@
                       *message =
                           "OpControlBarrier requires one of the following "
                           "Execution "
-                          "Models: TessellationControl, GLCompute or Kernel";
+                          "Models: TessellationControl, GLCompute, Kernel, "
+                          "MeshNV or TaskNV";
                     }
                     return false;
                   }
diff --git a/source/val/validate_builtins.cpp b/source/val/validate_builtins.cpp
index 379705a..40a36d0 100644
--- a/source/val/validate_builtins.cpp
+++ b/source/val/validate_builtins.cpp
@@ -1179,9 +1179,16 @@
           &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
           "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
           "used for variables with Input storage class if execution model is "
-          "Vertex.",
+          "MeshNV.",
           SpvExecutionModelMeshNV, decoration, built_in_inst,
           referenced_from_inst, std::placeholders::_1));
+      id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, vuid,
+          "Vulkan spec doesn't allow BuiltIn ClipDistance/CullDistance to be "
+          "used for variables with Input storage class if execution model is "
+          "MeshEXT.",
+          SpvExecutionModelMeshEXT, decoration, built_in_inst,
+          referenced_from_inst, std::placeholders::_1));
     }
 
     if (storage_class == SpvStorageClassOutput) {
@@ -1224,7 +1231,8 @@
         case SpvExecutionModelTessellationControl:
         case SpvExecutionModelTessellationEvaluation:
         case SpvExecutionModelGeometry:
-        case SpvExecutionModelMeshNV: {
+        case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT: {
           if (decoration.struct_member_index() != Decoration::kInvalidMember) {
             // The outer level of array is applied on the variable.
             if (spv_result_t error = ValidateF32Arr(
@@ -1856,7 +1864,8 @@
         case SpvExecutionModelTessellationControl:
         case SpvExecutionModelTessellationEvaluation:
         case SpvExecutionModelGeometry:
-        case SpvExecutionModelMeshNV: {
+        case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT: {
           // PointSize can be a per-vertex variable for tessellation control,
           // tessellation evaluation and geometry shader stages. In such cases
           // variables will have an array of 32-bit floats.
@@ -1957,6 +1966,13 @@
           "with Input storage class if execution model is MeshNV.",
           SpvExecutionModelMeshNV, decoration, built_in_inst,
           referenced_from_inst, std::placeholders::_1));
+      id_to_at_reference_checks_[referenced_from_inst.id()].push_back(std::bind(
+          &BuiltInsValidator::ValidateNotCalledWithExecutionModel, this, 4319,
+          "Vulkan spec doesn't allow BuiltIn Position to be used "
+          "for variables "
+          "with Input storage class if execution model is MeshEXT.",
+          SpvExecutionModelMeshEXT, decoration, built_in_inst,
+          referenced_from_inst, std::placeholders::_1));
     }
 
     for (const SpvExecutionModel execution_model : execution_models_) {
@@ -1980,7 +1996,8 @@
         case SpvExecutionModelGeometry:
         case SpvExecutionModelTessellationControl:
         case SpvExecutionModelTessellationEvaluation:
-        case SpvExecutionModelMeshNV: {
+        case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT: {
           // Position can be a per-vertex variable for tessellation control,
           // tessellation evaluation, geometry and mesh shader stages. In such
           // cases variables will have an array of 4-component 32-bit float
@@ -2151,6 +2168,7 @@
         case SpvExecutionModelTessellationEvaluation:
         case SpvExecutionModelGeometry:
         case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT:
         case SpvExecutionModelIntersectionKHR:
         case SpvExecutionModelAnyHitKHR:
         case SpvExecutionModelClosestHitKHR: {
@@ -2163,9 +2181,8 @@
                  << _.VkErrorID(4330)
                  << "Vulkan spec allows BuiltIn PrimitiveId to be used only "
                     "with Fragment, TessellationControl, "
-                    "TessellationEvaluation, Geometry, MeshNV, "
-                    "IntersectionKHR, "
-                    "AnyHitKHR, and ClosestHitKHR execution models. "
+                    "TessellationEvaluation, Geometry, MeshNV, MeshEXT, "
+                    "IntersectionKHR, AnyHitKHR, and ClosestHitKHR execution models. "
                  << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                      referenced_from_inst, execution_model);
         }
@@ -2713,7 +2730,8 @@
       assert(function_id_ == 0);
       for (const auto em :
            {SpvExecutionModelVertex, SpvExecutionModelTessellationEvaluation,
-            SpvExecutionModelGeometry, SpvExecutionModelMeshNV}) {
+            SpvExecutionModelGeometry, SpvExecutionModelMeshNV,
+            SpvExecutionModelMeshEXT}) {
         id_to_at_reference_checks_[referenced_from_inst.id()].push_back(
             std::bind(&BuiltInsValidator::ValidateNotCalledWithExecutionModel,
                       this, ((operand == SpvBuiltInLayer) ? 4274 : 4406),
@@ -2721,7 +2739,7 @@
                       "ViewportIndex to be "
                       "used for variables with Input storage class if "
                       "execution model is Vertex, TessellationEvaluation, "
-                      "Geometry, or MeshNV.",
+                      "Geometry, MeshNV or MeshEXT.",
                       em, decoration, built_in_inst, referenced_from_inst,
                       std::placeholders::_1));
       }
@@ -2746,6 +2764,7 @@
         case SpvExecutionModelGeometry:
         case SpvExecutionModelFragment:
         case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT:
           // Ok.
           break;
         case SpvExecutionModelVertex:
@@ -2925,7 +2944,10 @@
     for (const SpvExecutionModel execution_model : execution_models_) {
       bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute ||
                               execution_model == SpvExecutionModelTaskNV ||
-                              execution_model == SpvExecutionModelMeshNV;
+                              execution_model == SpvExecutionModelMeshNV ||
+                              execution_model == SpvExecutionModelTaskEXT ||
+                              execution_model == SpvExecutionModelMeshEXT;
+
       if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) {
         uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
         return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
@@ -2933,7 +2955,8 @@
                << spvLogStringForEnv(_.context()->target_env)
                << " spec allows BuiltIn "
                << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
-               << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
+               << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or"
+               << " TaskEXT execution model. "
                << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                    referenced_from_inst, execution_model);
       }
@@ -3007,7 +3030,9 @@
     for (const SpvExecutionModel execution_model : execution_models_) {
       bool has_vulkan_model = execution_model == SpvExecutionModelGLCompute ||
                               execution_model == SpvExecutionModelTaskNV ||
-                              execution_model == SpvExecutionModelMeshNV;
+                              execution_model == SpvExecutionModelMeshNV ||
+                              execution_model == SpvExecutionModelTaskEXT ||
+                              execution_model == SpvExecutionModelMeshEXT;
       if (spvIsVulkanEnv(_.context()->target_env) && !has_vulkan_model) {
         uint32_t vuid = GetVUIDForBuiltin(builtin, VUIDErrorExecutionModel);
         return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
@@ -3015,7 +3040,8 @@
                << spvLogStringForEnv(_.context()->target_env)
                << " spec allows BuiltIn "
                << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN, builtin)
-               << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
+               << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or "
+               << "TaskEXT execution model. "
                << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                    referenced_from_inst, execution_model);
       }
@@ -3159,14 +3185,17 @@
     for (const SpvExecutionModel execution_model : execution_models_) {
       if (execution_model != SpvExecutionModelGLCompute &&
           execution_model != SpvExecutionModelTaskNV &&
-          execution_model != SpvExecutionModelMeshNV) {
+          execution_model != SpvExecutionModelMeshNV &&
+          execution_model != SpvExecutionModelTaskEXT &&
+          execution_model != SpvExecutionModelMeshEXT) {
         return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
                << _.VkErrorID(4425)
                << spvLogStringForEnv(_.context()->target_env)
                << " spec allows BuiltIn "
                << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
                                                 decoration.params()[0])
-               << " to be used only with GLCompute, MeshNV, or TaskNV execution model. "
+               << " to be used only with GLCompute, MeshNV, TaskNV, MeshEXT or "
+               << "TaskEXT execution model. "
                << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                    referenced_from_inst, execution_model);
       }
@@ -3297,12 +3326,15 @@
     for (const SpvExecutionModel execution_model : execution_models_) {
       if (execution_model != SpvExecutionModelVertex &&
           execution_model != SpvExecutionModelMeshNV &&
-          execution_model != SpvExecutionModelTaskNV) {
+          execution_model != SpvExecutionModelTaskNV &&
+          execution_model != SpvExecutionModelMeshEXT &&
+          execution_model != SpvExecutionModelTaskEXT) {
         return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
                << _.VkErrorID(4207) << "Vulkan spec allows BuiltIn "
                << _.grammar().lookupOperandName(SPV_OPERAND_TYPE_BUILT_IN,
                                                 operand)
-               << " to be used only with Vertex, MeshNV, or TaskNV execution "
+               << " to be used only with Vertex, MeshNV, TaskNV , MeshEXT or"
+               << " TaskEXT execution "
                   "model. "
                << GetReferenceDesc(decoration, built_in_inst, referenced_inst,
                                    referenced_from_inst, execution_model);
@@ -3818,6 +3850,7 @@
         case SpvExecutionModelVertex:
         case SpvExecutionModelGeometry:
         case SpvExecutionModelMeshNV:
+        case SpvExecutionModelMeshEXT:
           break;
         default: {
           return _.diag(SPV_ERROR_INVALID_DATA, &referenced_from_inst)
@@ -4276,6 +4309,10 @@
     case SpvBuiltInMeshViewCountNV:
     case SpvBuiltInMeshViewIndicesNV:
     case SpvBuiltInCurrentRayTimeNV:
+    case SpvBuiltInPrimitivePointIndicesEXT:
+    case SpvBuiltInPrimitiveLineIndicesEXT:
+    case SpvBuiltInPrimitiveTriangleIndicesEXT:
+    case SpvBuiltInCullPrimitiveEXT:
       // No validation rules (for the moment).
       break;
 
diff --git a/source/val/validate_extensions.cpp b/source/val/validate_extensions.cpp
index fcf04e2..1e69cb3 100644
--- a/source/val/validate_extensions.cpp
+++ b/source/val/validate_extensions.cpp
@@ -756,10 +756,10 @@
   if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) {
     std::string extension = GetExtensionString(&(inst->c_inst()));
     if (extension ==
-        ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout)) {
+            ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
+        extension == ExtensionToString(kSPV_EXT_mesh_shader)) {
       return _.diag(SPV_ERROR_WRONG_VERSION, inst)
-             << "SPV_KHR_workgroup_memory_explicit_layout extension "
-                "requires SPIR-V version 1.4 or later.";
+             << extension << " extension requires SPIR-V version 1.4 or later.";
     }
   }
 
diff --git a/source/val/validate_memory.cpp b/source/val/validate_memory.cpp
index d4fca84..e4ad0e0 100644
--- a/source/val/validate_memory.cpp
+++ b/source/val/validate_memory.cpp
@@ -442,7 +442,8 @@
       storage_class != SpvStorageClassIncomingRayPayloadKHR &&
       storage_class != SpvStorageClassHitAttributeKHR &&
       storage_class != SpvStorageClassCallableDataKHR &&
-      storage_class != SpvStorageClassIncomingCallableDataKHR) {
+      storage_class != SpvStorageClassIncomingCallableDataKHR &&
+      storage_class != SpvStorageClassTaskPayloadWorkgroupEXT) {
     bool storage_input_or_output = storage_class == SpvStorageClassInput ||
                                    storage_class == SpvStorageClassOutput;
     bool builtin = false;
diff --git a/source/val/validate_mode_setting.cpp b/source/val/validate_mode_setting.cpp
index 67b10c5..09a9d48 100644
--- a/source/val/validate_mode_setting.cpp
+++ b/source/val/validate_mode_setting.cpp
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //
-#include "source/val/validate.h"
-
 #include <algorithm>
 
 #include "source/opcode.h"
 #include "source/spirv_target_env.h"
 #include "source/val/instruction.h"
+#include "source/val/validate.h"
 #include "source/val/validation_state.h"
 
 namespace spvtools {
@@ -359,14 +358,18 @@
                              return true;
                            case SpvExecutionModelMeshNV:
                              return _.HasCapability(SpvCapabilityMeshShadingNV);
+                           case SpvExecutionModelMeshEXT:
+                             return _.HasCapability(
+                                 SpvCapabilityMeshShadingEXT);
                            default:
                              return false;
                          }
                        })) {
-        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
+        if (_.HasCapability(SpvCapabilityMeshShadingNV) ||
+            _.HasCapability(SpvCapabilityMeshShadingEXT)) {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
-                 << "Execution mode can only be used with the Geometry or "
-                    "MeshNV execution model.";
+                 << "Execution mode can only be used with the Geometry "
+                    "MeshNV or MeshEXT execution model.";
         } else {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
                  << "Execution mode can only be used with the Geometry "
@@ -421,14 +424,18 @@
                              return true;
                            case SpvExecutionModelMeshNV:
                              return _.HasCapability(SpvCapabilityMeshShadingNV);
+                           case SpvExecutionModelMeshEXT:
+                             return _.HasCapability(
+                                 SpvCapabilityMeshShadingEXT);
                            default:
                              return false;
                          }
                        })) {
-        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
+        if (_.HasCapability(SpvCapabilityMeshShadingNV) ||
+            _.HasCapability(SpvCapabilityMeshShadingEXT)) {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
                  << "Execution mode can only be used with a Geometry, "
-                    "tessellation or MeshNV execution model.";
+                    "tessellation, MeshNV or MeshEXT execution model.";
         } else {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
                  << "Execution mode can only be used with a Geometry or "
@@ -494,14 +501,19 @@
                            case SpvExecutionModelTaskNV:
                            case SpvExecutionModelMeshNV:
                              return _.HasCapability(SpvCapabilityMeshShadingNV);
+                           case SpvExecutionModelTaskEXT:
+                           case SpvExecutionModelMeshEXT:
+                             return _.HasCapability(
+                                 SpvCapabilityMeshShadingEXT);
                            default:
                              return false;
                          }
                        })) {
-        if (_.HasCapability(SpvCapabilityMeshShadingNV)) {
+        if (_.HasCapability(SpvCapabilityMeshShadingNV) ||
+            _.HasCapability(SpvCapabilityMeshShadingEXT)) {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
                  << "Execution mode can only be used with a Kernel, GLCompute, "
-                    "MeshNV, or TaskNV execution model.";
+                    "MeshNV, MeshEXT, TaskNV or TaskEXT execution model.";
         } else {
           return _.diag(SPV_ERROR_INVALID_DATA, inst)
                  << "Execution mode can only be used with a Kernel or "
diff --git a/source/val/validate_scopes.cpp b/source/val/validate_scopes.cpp
index a5f3db1..5fb661b 100644
--- a/source/val/validate_scopes.cpp
+++ b/source/val/validate_scopes.cpp
@@ -144,14 +144,16 @@
               [errorVUID](SpvExecutionModel model, std::string* message) {
                 if (model != SpvExecutionModelTaskNV &&
                     model != SpvExecutionModelMeshNV &&
+                    model != SpvExecutionModelTaskEXT &&
+                    model != SpvExecutionModelMeshEXT &&
                     model != SpvExecutionModelTessellationControl &&
                     model != SpvExecutionModelGLCompute) {
                   if (message) {
                     *message =
                         errorVUID +
                         "in Vulkan environment, Workgroup execution scope is "
-                        "only for TaskNV, MeshNV, TessellationControl, and "
-                        "GLCompute execution models";
+                        "only for TaskNV, MeshNV, TaskEXT, MeshEXT, "
+                        "TessellationControl, and GLCompute execution models";
                   }
                   return false;
                 }
@@ -269,11 +271,14 @@
               [errorVUID](SpvExecutionModel model, std::string* message) {
                 if (model != SpvExecutionModelGLCompute &&
                     model != SpvExecutionModelTaskNV &&
-                    model != SpvExecutionModelMeshNV) {
+                    model != SpvExecutionModelMeshNV &&
+                    model != SpvExecutionModelTaskEXT &&
+                    model != SpvExecutionModelMeshEXT) {
                   if (message) {
                     *message = errorVUID +
                                "Workgroup Memory Scope is limited to MeshNV, "
-                               "TaskNV, and GLCompute execution model";
+                               "TaskNV, MeshEXT, TaskEXT and GLCompute "
+                               "execution model";
                   }
                   return false;
                 }
diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp
index 3501e8c..2e1fa31 100644
--- a/source/val/validation_state.cpp
+++ b/source/val/validation_state.cpp
@@ -639,7 +639,9 @@
                                                  std::string* message) {
             if (model != SpvExecutionModelGLCompute &&
                 model != SpvExecutionModelTaskNV &&
-                model != SpvExecutionModelMeshNV) {
+                model != SpvExecutionModelMeshNV &&
+                model != SpvExecutionModelTaskEXT &&
+                model != SpvExecutionModelMeshEXT) {
               if (message) {
                 *message =
                     errorVUID +
@@ -1522,6 +1524,7 @@
       case SpvStorageClassCallableDataKHR:
       case SpvStorageClassIncomingCallableDataKHR:
       case SpvStorageClassShaderRecordBufferKHR:
+      case SpvStorageClassTaskPayloadWorkgroupEXT:
         return true;
       default:
         return false;
diff --git a/test/operand_capabilities_test.cpp b/test/operand_capabilities_test.cpp
index bc0ee05..6050346 100644
--- a/test/operand_capabilities_test.cpp
+++ b/test/operand_capabilities_test.cpp
@@ -97,6 +97,14 @@
     }                                                                \
   }
 
+#define CASE6(TYPE, VALUE, CAP1, CAP2, CAP3, CAP4, CAP5, CAP6)          \
+  {                                                                     \
+    SPV_OPERAND_TYPE_##TYPE, uint32_t(Spv##VALUE), CapabilitySet {      \
+      SpvCapability##CAP1, SpvCapability##CAP2, SpvCapability##CAP3,    \
+          SpvCapability##CAP4, SpvCapability##CAP5, SpvCapability##CAP6 \
+    }                                                                   \
+  }
+
 // See SPIR-V Section 3.3 Execution Model
 INSTANTIATE_TEST_SUITE_P(
     ExecutionModel, EnumCapabilityTest,
@@ -168,10 +176,10 @@
                   Geometry),
             CASE1(EXECUTION_MODE, ExecutionModeQuads, Tessellation),
             CASE1(EXECUTION_MODE, ExecutionModeIsolines, Tessellation),
-            CASE3(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry,
-                  Tessellation, MeshShadingNV),
-            CASE2(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry,
-                  MeshShadingNV),
+            CASE4(EXECUTION_MODE, ExecutionModeOutputVertices, Geometry,
+                  Tessellation, MeshShadingNV, MeshShadingEXT),
+            CASE3(EXECUTION_MODE, ExecutionModeOutputPoints, Geometry,
+                  MeshShadingNV, MeshShadingEXT),
             CASE1(EXECUTION_MODE, ExecutionModeOutputLineStrip, Geometry),
             CASE1(EXECUTION_MODE, ExecutionModeOutputTriangleStrip, Geometry),
             CASE1(EXECUTION_MODE, ExecutionModeVecTypeHint, Kernel),
@@ -486,11 +494,11 @@
             CASE1(BUILT_IN, BuiltInCullDistance, CullDistance),  // Bug 1407, 15234
             CASE1(BUILT_IN, BuiltInVertexId, Shader),
             CASE1(BUILT_IN, BuiltInInstanceId, Shader),
-            CASE5(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation,
-                  RayTracingNV, RayTracingKHR, MeshShadingNV),
+            CASE6(BUILT_IN, BuiltInPrimitiveId, Geometry, Tessellation,
+                  RayTracingNV, RayTracingKHR, MeshShadingNV, MeshShadingEXT),
             CASE2(BUILT_IN, BuiltInInvocationId, Geometry, Tessellation),
-            CASE3(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV),
-            CASE3(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV),  // Bug 15234
+            CASE4(BUILT_IN, BuiltInLayer, Geometry, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT),
+            CASE4(BUILT_IN, BuiltInViewportIndex, MultiViewport, ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT),  // Bug 15234
             CASE1(BUILT_IN, BuiltInTessLevelOuter, Tessellation),
             CASE1(BUILT_IN, BuiltInTessLevelInner, Tessellation),
             CASE1(BUILT_IN, BuiltInTessCoord, Tessellation),
@@ -533,11 +541,11 @@
         Values(SPV_ENV_UNIVERSAL_1_5),
         ValuesIn(std::vector<EnumCapabilityCase>{
             // SPIR-V 1.5 adds new capabilities to enable these two builtins.
-            CASE4(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer,
-                  ShaderViewportIndexLayerEXT, MeshShadingNV),
-            CASE4(BUILT_IN, BuiltInViewportIndex, MultiViewport,
+            CASE5(BUILT_IN, BuiltInLayer, Geometry, ShaderLayer,
+                  ShaderViewportIndexLayerEXT, MeshShadingNV, MeshShadingEXT),
+            CASE5(BUILT_IN, BuiltInViewportIndex, MultiViewport,
                   ShaderViewportIndex, ShaderViewportIndexLayerEXT,
-                  MeshShadingNV),
+                  MeshShadingNV, MeshShadingEXT),
         })));
 
 // See SPIR-V Section 3.22 Selection Control
diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp
index a0308d5..a7e4055 100644
--- a/test/val/val_atomics_test.cpp
+++ b/test/val/val_atomics_test.cpp
@@ -778,8 +778,8 @@
   EXPECT_THAT(
       getDiagnosticString(),
       HasSubstr("AtomicStore: Vulkan spec only allows storage classes for "
-                "atomic to be: Uniform, Workgroup, Image, StorageBuffer, or "
-                "PhysicalStorageBuffer."));
+                "atomic to be: Uniform, Workgroup, Image, StorageBuffer, "
+                "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT."));
 }
 
 TEST_F(ValidateAtomics, AtomicStoreFunctionPointerStorageType) {
diff --git a/test/val/val_barriers_test.cpp b/test/val/val_barriers_test.cpp
index df5ee16..2569de0 100644
--- a/test/val/val_barriers_test.cpp
+++ b/test/val/val_barriers_test.cpp
@@ -254,8 +254,9 @@
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_UNIVERSAL_1_2));
   EXPECT_THAT(
       getDiagnosticString(),
-      HasSubstr("OpControlBarrier requires one of the following Execution "
-                "Models: TessellationControl, GLCompute or Kernel"));
+      HasSubstr("OpControlBarrier requires one of the following "
+                "Execution Models: TessellationControl, GLCompute, Kernel, "
+                "MeshNV or TaskNV"));
 }
 
 TEST_F(ValidateBarriers, OpControlBarrierExecutionModelFragmentSpirv13) {
@@ -417,8 +418,9 @@
   EXPECT_THAT(getDiagnosticString(),
               AnyVUID("VUID-StandaloneSpirv-None-04639"));
   EXPECT_THAT(getDiagnosticString(),
-              HasSubstr("Workgroup Memory Scope is limited to MeshNV, TaskNV, "
-                        "and GLCompute execution model"));
+              HasSubstr("Workgroup Memory Scope is limited to MeshNV, "
+                        "TaskNV, MeshEXT, TaskEXT and GLCompute "
+                        "execution model"));
 }
 
 TEST_F(ValidateBarriers,
@@ -433,8 +435,8 @@
               AnyVUID("VUID-StandaloneSpirv-None-04637"));
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("in Vulkan environment, Workgroup execution scope is "
-                        "only for TaskNV, MeshNV, TessellationControl, and "
-                        "GLCompute execution models"));
+                        "only for TaskNV, MeshNV, TaskEXT, MeshEXT, "
+                        "TessellationControl, and GLCompute execution models"));
 }
 
 TEST_F(ValidateBarriers, OpControlBarrierVulkan1p1WorkgroupComputeSuccess) {
@@ -544,10 +546,11 @@
   CompileSuccessfully(GenerateShaderCode(body, "", "Fragment"),
                       SPV_ENV_VULKAN_1_0);
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("OpControlBarrier requires one of the following Execution "
-                "Models: TessellationControl, GLCompute or Kernel"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("OpControlBarrier requires one of the following "
+                        "Execution "
+                        "Models: TessellationControl, GLCompute, Kernel, "
+                        "MeshNV or TaskNV"));
 }
 
 TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionVertex1p1) {
@@ -588,8 +591,9 @@
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
   EXPECT_THAT(
       getDiagnosticString(),
-      HasSubstr("OpControlBarrier requires one of the following Execution "
-                "Models: TessellationControl, GLCompute or Kernel"));
+      HasSubstr("OpControlBarrier requires one of the following "
+                "Execution Models: TessellationControl, GLCompute, Kernel, "
+                "MeshNV or TaskNV"));
 }
 
 TEST_F(ValidateBarriers, OpControlBarrierSubgroupExecutionGeometry1p1) {
@@ -631,10 +635,11 @@
       GenerateShaderCode(body, "OpCapability Geometry\n", "Geometry"),
       SPV_ENV_VULKAN_1_0);
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("OpControlBarrier requires one of the following Execution "
-                "Models: TessellationControl, GLCompute or Kernel"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("OpControlBarrier requires one of the following "
+                        "Execution "
+                        "Models: TessellationControl, GLCompute, Kernel, "
+                        "MeshNV or TaskNV"));
 }
 
 TEST_F(ValidateBarriers,
@@ -679,10 +684,11 @@
                                          "TessellationEvaluation"),
                       SPV_ENV_VULKAN_1_0);
   ASSERT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("OpControlBarrier requires one of the following Execution "
-                "Models: TessellationControl, GLCompute or Kernel"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("OpControlBarrier requires one of the following "
+                        "Execution "
+                        "Models: TessellationControl, GLCompute, Kernel, "
+                        "MeshNV or TaskNV"));
 }
 
 TEST_F(ValidateBarriers, OpMemoryBarrierSuccess) {
diff --git a/test/val/val_builtins_test.cpp b/test/val/val_builtins_test.cpp
index 2cbe9a8..40832e0 100644
--- a/test/val/val_builtins_test.cpp
+++ b/test/val/val_builtins_test.cpp
@@ -784,8 +784,8 @@
                    "VUID-NumWorkgroups-NumWorkgroups-04296 "
                    "VUID-WorkgroupId-WorkgroupId-04422"),
             Values(TestResult(SPV_ERROR_INVALID_DATA,
-                              "to be used only with GLCompute, MeshNV, or "
-                              "TaskNV execution model"))));
+                              "to be used only with GLCompute, MeshNV, "
+                              "TaskNV, MeshEXT or TaskEXT execution model"))));
 
 INSTANTIATE_TEST_SUITE_P(
     ComputeShaderInputInt32Vec3NotInput,
@@ -1006,7 +1006,7 @@
         Values("VUID-Layer-Layer-04274 VUID-ViewportIndex-ViewportIndex-04406"),
         Values(TestResult(SPV_ERROR_INVALID_DATA,
                           "Input storage class if execution model is Vertex, "
-                          "TessellationEvaluation, Geometry, or MeshNV",
+                          "TessellationEvaluation, Geometry, MeshNV or MeshEXT",
                           "which is called with execution model"))));
 
 INSTANTIATE_TEST_SUITE_P(
@@ -1311,14 +1311,14 @@
 INSTANTIATE_TEST_SUITE_P(
     PrimitiveIdInvalidExecutionModel,
     ValidateVulkanCombineBuiltInExecutionModelDataTypeResult,
-    Combine(Values("PrimitiveId"), Values("Vertex", "GLCompute"),
-            Values("Input"), Values("%u32"),
-            Values("VUID-PrimitiveId-PrimitiveId-04330"),
-            Values(TestResult(
-                SPV_ERROR_INVALID_DATA,
-                "to be used only with Fragment, TessellationControl, "
-                "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, "
-                "AnyHitKHR, and ClosestHitKHR execution models"))));
+    Combine(
+        Values("PrimitiveId"), Values("Vertex", "GLCompute"), Values("Input"),
+        Values("%u32"), Values("VUID-PrimitiveId-PrimitiveId-04330"),
+        Values(TestResult(SPV_ERROR_INVALID_DATA,
+                          "to be used only with Fragment, TessellationControl, "
+                          "TessellationEvaluation, Geometry, MeshNV, MeshEXT, "
+                          "IntersectionKHR, "
+                          "AnyHitKHR, and ClosestHitKHR execution models"))));
 
 INSTANTIATE_TEST_SUITE_P(
     PrimitiveIdFragmentNotInput,
@@ -1867,16 +1867,18 @@
 INSTANTIATE_TEST_SUITE_P(
     DrawIndexInvalidExecutionModel,
     ValidateVulkanCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
-    Combine(Values("DrawIndex"),
-            Values("Fragment", "GLCompute", "Geometry", "TessellationControl",
-                   "TessellationEvaluation"),
-            Values("Input"), Values("%u32"),
-            Values("OpCapability DrawParameters\n"),
-            Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
-            Values("VUID-DrawIndex-DrawIndex-04207"),
-            Values(TestResult(SPV_ERROR_INVALID_DATA,
-                              "to be used only with Vertex, MeshNV, or TaskNV "
-                              "execution model"))));
+    Combine(
+        Values("DrawIndex"),
+        Values("Fragment", "GLCompute", "Geometry", "TessellationControl",
+               "TessellationEvaluation"),
+        Values("Input"), Values("%u32"),
+        Values("OpCapability DrawParameters\n"),
+        Values("OpExtension \"SPV_KHR_shader_draw_parameters\"\n"),
+        Values("VUID-DrawIndex-DrawIndex-04207"),
+        Values(TestResult(
+            SPV_ERROR_INVALID_DATA,
+            "to be used only with Vertex, MeshNV, TaskNV , MeshEXT or TaskEXT "
+            "execution model"))));
 
 INSTANTIATE_TEST_SUITE_P(
     DrawIndexNotInput,
@@ -2164,17 +2166,17 @@
 INSTANTIATE_TEST_SUITE_P(
     PrimitiveIdRTNotExecutionMode,
     ValidateGenericCombineBuiltInExecutionModelDataTypeCapabilityExtensionResult,
-    Combine(Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
-            Values("RayGenerationKHR", "MissKHR", "CallableKHR"),
-            Values("Input"), Values("%u32"),
-            Values("OpCapability RayTracingKHR\n"),
-            Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
-            Values("VUID-PrimitiveId-PrimitiveId-04330"),
-            Values(TestResult(
-                SPV_ERROR_INVALID_DATA,
-                "to be used only with Fragment, TessellationControl, "
-                "TessellationEvaluation, Geometry, MeshNV, IntersectionKHR, "
-                "AnyHitKHR, and ClosestHitKHR execution models"))));
+    Combine(
+        Values(SPV_ENV_VULKAN_1_2), Values("PrimitiveId"),
+        Values("RayGenerationKHR", "MissKHR", "CallableKHR"), Values("Input"),
+        Values("%u32"), Values("OpCapability RayTracingKHR\n"),
+        Values("OpExtension \"SPV_KHR_ray_tracing\"\n"),
+        Values("VUID-PrimitiveId-PrimitiveId-04330"),
+        Values(TestResult(SPV_ERROR_INVALID_DATA,
+                          "to be used only with Fragment, TessellationControl, "
+                          "TessellationEvaluation, Geometry, MeshNV, MeshEXT, "
+                          "IntersectionKHR, "
+                          "AnyHitKHR, and ClosestHitKHR execution models"))));
 
 INSTANTIATE_TEST_SUITE_P(
     PrimitiveIdRTNotInput,
@@ -2896,10 +2898,10 @@
 
   CompileSuccessfully(generator.Build(), SPV_ENV_VULKAN_1_0);
   ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions(SPV_ENV_VULKAN_1_0));
-  EXPECT_THAT(
-      getDiagnosticString(),
-      HasSubstr("Vulkan spec allows BuiltIn WorkgroupSize to be used "
-                "only with GLCompute, MeshNV, or TaskNV execution model"));
+  EXPECT_THAT(getDiagnosticString(),
+              HasSubstr("Vulkan spec allows BuiltIn WorkgroupSize to be used "
+                        "only with GLCompute, MeshNV, TaskNV, MeshEXT or "
+                        "TaskEXT execution model"));
   EXPECT_THAT(getDiagnosticString(),
               HasSubstr("is referencing ID <2> (OpConstantComposite) which is "
                         "decorated with BuiltIn WorkgroupSize in function <1> "
@@ -3356,7 +3358,7 @@
 OpFunctionEnd
 )";
 
-    generator.add_at_the_end_ = function_body;
+  generator.add_at_the_end_ = function_body;
 
   return generator;
 }
@@ -3419,7 +3421,7 @@
 OpFunctionEnd
 )";
 
-    generator.add_at_the_end_ = function_body;
+  generator.add_at_the_end_ = function_body;
 
   return generator;
 }
@@ -3437,7 +3439,6 @@
               HasSubstr("VUID-FragDepth-FragDepth-04216"));
 }
 
-
 TEST_F(ValidateBuiltIns, AllowInstanceIdWithIntersectionShader) {
   CodeGenerator generator = CodeGenerator::GetDefaultShaderCodeGenerator();
   generator.capabilities_ += R"(
@@ -3766,8 +3767,8 @@
             Values("VUID-SubgroupId-SubgroupId-04367 "
                    "VUID-NumSubgroups-NumSubgroups-04293"),
             Values(TestResult(SPV_ERROR_INVALID_DATA,
-                              "to be used only with GLCompute, MeshNV, or "
-                              "TaskNV execution model"))));
+                              "to be used only with GLCompute, MeshNV, "
+                              "TaskNV, MeshEXT or TaskEXT execution model"))));
 
 INSTANTIATE_TEST_SUITE_P(
     SubgroupNumAndIdNotU32, ValidateVulkanSubgroupBuiltIns,