Add validation for SPV_EXT_shader_atomic_float16_add (#4325)

diff --git a/source/val/validate_atomics.cpp b/source/val/validate_atomics.cpp
index fa53ca1..da023b8 100644
--- a/source/val/validate_atomics.cpp
+++ b/source/val/validate_atomics.cpp
@@ -222,6 +222,13 @@
 
         if (opcode == SpvOpAtomicFAddEXT) {
           // result type being float checked already
+          if ((_.GetBitWidth(result_type) == 16) &&
+              (!_.HasCapability(SpvCapabilityAtomicFloat16AddEXT))) {
+            return _.diag(SPV_ERROR_INVALID_DATA, inst)
+                   << spvOpcodeString(opcode)
+                   << ": float add atomics require the AtomicFloat32AddEXT "
+                      "capability";
+          }
           if ((_.GetBitWidth(result_type) == 32) &&
               (!_.HasCapability(SpvCapabilityAtomicFloat32AddEXT))) {
             return _.diag(SPV_ERROR_INVALID_DATA, inst)
diff --git a/test/val/val_atomics_test.cpp b/test/val/val_atomics_test.cpp
index fc3aedb..b7f6948 100644
--- a/test/val/val_atomics_test.cpp
+++ b/test/val/val_atomics_test.cpp
@@ -318,7 +318,7 @@
   EXPECT_THAT(
       getDiagnosticString(),
       HasSubstr("Opcode AtomicFAddEXT requires one of these capabilities: "
-                "AtomicFloat32AddEXT AtomicFloat64AddEXT"));
+                "AtomicFloat32AddEXT AtomicFloat64AddEXT AtomicFloat16AddEXT"));
 }
 
 TEST_F(ValidateAtomics, AtomicMinFloatVulkan) {
@@ -539,6 +539,27 @@
                         "require the AtomicFloat32MinMaxEXT capability"));
 }
 
+TEST_F(ValidateAtomics, AtomicAddFloat16VulkanSuccess) {
+  const std::string defs = R"(
+%f16 = OpTypeFloat 16
+%f16_1 = OpConstant %f16 1
+%f16_ptr = OpTypePointer Workgroup %f16
+%f16_var = OpVariable %f16_ptr Workgroup
+)";
+  const std::string body = R"(
+%val1 = OpAtomicFAddEXT %f16 %f16_var %device %relaxed %f16_1
+)";
+  const std::string extra = R"(
+OpCapability Float16
+OpCapability AtomicFloat16AddEXT
+OpExtension "SPV_EXT_shader_atomic_float16_add"
+)";
+
+  CompileSuccessfully(GenerateShaderComputeCode(body, extra, defs),
+                      SPV_ENV_VULKAN_1_0);
+  ASSERT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0));
+}
+
 TEST_F(ValidateAtomics, AtomicAddFloatVulkanSuccess) {
   const std::string body = R"(
 %val1 = OpAtomicFAddEXT %f32 %f32_var %device %relaxed %f32_1