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'");