Add changes for SPV_EXT_shader_atomic_float_add
diff --git a/SPIRV/GLSL.ext.EXT.h b/SPIRV/GLSL.ext.EXT.h
index 40164b6..6eb0eee 100644
--- a/SPIRV/GLSL.ext.EXT.h
+++ b/SPIRV/GLSL.ext.EXT.h
@@ -35,5 +35,6 @@
 static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
 static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
 static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
+static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_atomic_float_add";
 
 #endif  // #ifndef GLSLextEXT_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 3baa1f4..b14a3b2 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -6682,6 +6682,14 @@
     case glslang::EOpImageAtomicAdd:
     case glslang::EOpAtomicCounterAdd:
         opCode = spv::OpAtomicIAdd;
+        if (typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble) {
+            opCode = spv::OpAtomicFAddEXT;
+            builder.addExtension(spv::E_SPV_EXT_shader_atomic_float_add);
+            if (typeProxy == glslang::EbtFloat)
+                builder.addCapability(spv::CapabilityAtomicFloat32AddEXT);
+            else
+                builder.addCapability(spv::CapabilityAtomicFloat64AddEXT);
+        }
         break;
     case glslang::EOpAtomicCounterSubtract:
         opCode = spv::OpAtomicISub;
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index b1f2b82..4829bb4 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -938,6 +938,9 @@
 
     case CapabilityIntegerFunctions2INTEL:              return "CapabilityIntegerFunctions2INTEL";
 
+    case CapabilityAtomicFloat32AddEXT:                     return "AtomicFloat32AddEXT";
+    case CapabilityAtomicFloat64AddEXT:                     return "AtomicFloat64AddEXT";
+
     default: return "Bad";
     }
 }
@@ -1313,6 +1316,8 @@
     case 4430: return "OpSubgroupAllEqualKHR";
     case 4432: return "OpSubgroupReadInvocationKHR";
 
+    case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
+
     case 5000: return "OpGroupIAddNonUniformAMD";
     case 5001: return "OpGroupFAddNonUniformAMD";
     case 5002: return "OpGroupFMinNonUniformAMD";
@@ -2260,6 +2265,11 @@
     InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'");
     InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'");
 
+    InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'");
+    InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'");
+    InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'");
+    InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'");
+
     InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'");
     InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
     InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");