Commit 79b93923 by Vikram Kushwaha

Add changes for SPV_EXT_shader_atomic_float_add

parent 1c42d4ee
...@@ -35,5 +35,6 @@ static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shade ...@@ -35,5 +35,6 @@ static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shade
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered"; 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_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_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 #endif // #ifndef GLSLextEXT_H
...@@ -6682,6 +6682,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv ...@@ -6682,6 +6682,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
case glslang::EOpImageAtomicAdd: case glslang::EOpImageAtomicAdd:
case glslang::EOpAtomicCounterAdd: case glslang::EOpAtomicCounterAdd:
opCode = spv::OpAtomicIAdd; 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; break;
case glslang::EOpAtomicCounterSubtract: case glslang::EOpAtomicCounterSubtract:
opCode = spv::OpAtomicISub; opCode = spv::OpAtomicISub;
......
...@@ -938,6 +938,9 @@ const char* CapabilityString(int info) ...@@ -938,6 +938,9 @@ const char* CapabilityString(int info)
case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL"; case CapabilityIntegerFunctions2INTEL: return "CapabilityIntegerFunctions2INTEL";
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
default: return "Bad"; default: return "Bad";
} }
} }
...@@ -1313,6 +1316,8 @@ const char* OpcodeString(int op) ...@@ -1313,6 +1316,8 @@ const char* OpcodeString(int op)
case 4430: return "OpSubgroupAllEqualKHR"; case 4430: return "OpSubgroupAllEqualKHR";
case 4432: return "OpSubgroupReadInvocationKHR"; case 4432: return "OpSubgroupReadInvocationKHR";
case OpAtomicFAddEXT: return "OpAtomicFAddEXT";
case 5000: return "OpGroupIAddNonUniformAMD"; case 5000: return "OpGroupIAddNonUniformAMD";
case 5001: return "OpGroupFAddNonUniformAMD"; case 5001: return "OpGroupFAddNonUniformAMD";
case 5002: return "OpGroupFMinNonUniformAMD"; case 5002: return "OpGroupFMinNonUniformAMD";
...@@ -2260,6 +2265,11 @@ void Parameterize() ...@@ -2260,6 +2265,11 @@ void Parameterize()
InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'"); 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(OperandId, "'Pointer'");
InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'"); InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'");
InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'"); InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'");
......
spv.atomicFloat_Error.comp
ERROR: 0:25: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:26: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:27: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:28: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:31: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:32: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:33: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:34: 'atomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:37: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:38: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:39: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:40: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:43: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:44: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:45: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:46: 'atomicExchange' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:50: 'atomicLoad' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:51: 'atomicStore' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:52: 'atomicLoad' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:53: 'atomicStore' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:56: 'atomicLoad' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:57: 'atomicStore' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:58: 'atomicLoad' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:59: 'atomicStore' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:63: 'imageAtomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:64: 'imageAtomicAdd' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:66: 'imageAtomicLoad' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:67: 'imageAtomicStore' : required extension not requested: GL_EXT_shader_atomic_float
ERROR: 0:80: 'atomicAdd' : no matching overloaded function found
ERROR: 0:81: 'atomicAdd' : no matching overloaded function found
ERROR: 0:82: 'atomicAdd' : no matching overloaded function found
ERROR: 0:83: 'atomicAdd' : no matching overloaded function found
ERROR: 0:86: 'atomicExchange' : no matching overloaded function found
ERROR: 0:87: 'atomicExchange' : no matching overloaded function found
ERROR: 0:88: 'atomicExchange' : no matching overloaded function found
ERROR: 0:89: 'atomicExchange' : no matching overloaded function found
ERROR: 0:90: 'atomicExchange' : no matching overloaded function found
ERROR: 0:91: 'atomicExchange' : no matching overloaded function found
ERROR: 0:95: 'atomicLoad' : no matching overloaded function found
ERROR: 0:96: 'atomicStore' : no matching overloaded function found
ERROR: 0:99: 'imageAtomicAdd' : no matching overloaded function found
ERROR: 0:100: 'imageAtomicAdd' : no matching overloaded function found
ERROR: 0:101: 'imageAtomicAdd' : no matching overloaded function found
ERROR: 0:102: 'imageAtomicExchange' : no matching overloaded function found
ERROR: 0:103: 'imageAtomicExchange' : no matching overloaded function found
ERROR: 0:104: 'imageAtomicExchange' : no matching overloaded function found
ERROR: 0:105: 'imageAtomicLoad' : no matching overloaded function found
ERROR: 0:106: 'imageAtomicLoad' : no matching overloaded function found
ERROR: 0:107: 'imageAtomicLoad' : no matching overloaded function found
ERROR: 0:108: 'imageAtomicStore' : no matching overloaded function found
ERROR: 0:109: 'imageAtomicStore' : no matching overloaded function found
ERROR: 0:110: 'imageAtomicStore' : no matching overloaded function found
ERROR: 52 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_EXT_shader_atomic_float: enable
#pragma use_vulkan_memory_model
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0) buffer Buffer
{
float dataf;
double datad;
} buf;
shared float atomf;
shared double atomd;
layout(binding = 0, r32f) volatile coherent uniform image1D fimage1D;
layout(binding = 1, r32f) volatile coherent uniform image1DArray fimage1DArray;
layout(binding = 2, r32f) volatile coherent uniform image2D fimage2D;
layout(binding = 3, r32f) volatile coherent uniform image2DArray fimage2DArray;
layout(binding = 4, r32f) volatile coherent uniform image2DRect fimage2DRect;
layout(binding = 5, r32f) volatile coherent uniform imageCube fimageCube;
layout(binding = 6, r32f) volatile coherent uniform imageCubeArray fimageCubeArray;
layout(binding = 9, r32f) volatile coherent uniform image3D fimage3D;
void main()
{
//atomicAdd
float resultf = 0;
resultf = atomicAdd(atomf, 3.0);
resultf = atomicAdd(atomf, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
resultf = atomicAdd(buf.dataf, 3.0);
resultf = atomicAdd(buf.dataf, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
double resultd = 0;
resultd = atomicAdd(atomd, 3.0);
resultd = atomicAdd(atomd, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
resultd = atomicAdd(buf.datad, 3.0);
resultd = atomicAdd(buf.datad, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
//atomicExchange
resultf = atomicExchange(buf.dataf, resultf);
buf.dataf += resultf;
resultf = atomicExchange(buf.dataf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultf = atomicExchange(atomf, resultf);
buf.dataf += resultf;
resultf = atomicExchange(atomf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultd = atomicExchange(buf.datad, resultd);
buf.datad += resultd;
resultd = atomicExchange(buf.datad, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
resultd = atomicExchange(atomd, resultd);
buf.datad += resultd;
resultd = atomicExchange(atomd, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
//atomic load/store
resultf = atomicLoad(buf.dataf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(buf.dataf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultf = atomicLoad(atomf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(atomf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultd = atomicLoad(buf.datad, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(buf.datad, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
resultd = atomicLoad(atomd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(atomd, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
// image atomics on 1D:
atomf = imageAtomicAdd(fimage1D, int(0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage1D, int(1), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage1D, int(1), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage1D, int(1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage1D, int(2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on 1D Array:
atomf = imageAtomicAdd(fimage1DArray, ivec2(0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage1DArray, ivec2(1,1), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage1DArray, ivec2(1,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage1DArray, ivec2(1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage1DArray, ivec2(2,2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on 2D:
atomf = imageAtomicAdd(fimage2D, ivec2(0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage2D, ivec2(1,1), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage2D, ivec2(1,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage2D, ivec2(1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage2D, ivec2(2,2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on 2D Rect:
atomf = imageAtomicAdd(fimage2DRect, ivec2(0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage2DRect, ivec2(1,1), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage2DRect, ivec2(1,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage2DRect, ivec2(1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage2DRect, ivec2(2,2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on 2D Array:
atomf = imageAtomicAdd(fimage2DArray, ivec3(0,0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage2DArray, ivec3(1,1,0), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage2DArray, ivec3(1,0,1), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage2DArray, ivec3(1,1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage2DArray, ivec3(2,2,0), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on Cube:
atomf = imageAtomicAdd(fimageCube, ivec3(0,0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimageCube, ivec3(1,1,0), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimageCube, ivec3(1,0,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimageCube, ivec3(1,1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimageCube, ivec3(2,2,1), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on Cube Array:
atomf = imageAtomicAdd(fimageCubeArray, ivec3(0,0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimageCubeArray, ivec3(1,1,0), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimageCubeArray, ivec3(1,0,1), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimageCubeArray, ivec3(1,1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimageCubeArray, ivec3(2,2,0), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
// image atomics on 3D:
atomf = imageAtomicAdd(fimage3D, ivec3(0,0,0), 2.0);
buf.dataf += atomf;
atomf = imageAtomicAdd(fimage3D, ivec3(1,1,0), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicExchange(fimage3D, ivec3(1,0,1), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
atomf = imageAtomicLoad(fimage3D, ivec3(1,1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
imageAtomicStore(fimage3D, ivec3(2,2,0), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
}
\ No newline at end of file
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#pragma use_vulkan_memory_model
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0) buffer Buffer
{
int datai;
float dataf;
double datad;
} buf;
shared int atomi;
shared float atomf;
shared double atomd;
layout(binding = 0, r32f) volatile coherent uniform image1D fimage1D;
layout(binding = 1, r32f) volatile coherent uniform image2D fimage2D;
void undeclared_errors()
{
//atomicAdd
float resultf = 0;
resultf = atomicAdd(atomf, 3.0);
resultf = atomicAdd(atomf, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
resultf = atomicAdd(buf.dataf, 3.0);
resultf = atomicAdd(buf.dataf, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
double resultd = 0;
resultd = atomicAdd(atomd, 3.0);
resultd = atomicAdd(atomd, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
resultd = atomicAdd(buf.datad, 3.0);
resultd = atomicAdd(buf.datad, 4.5, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
//atomicExchange
resultf = atomicExchange(buf.dataf, resultf);
resultf = atomicExchange(buf.dataf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultf = atomicExchange(atomf, resultf);
resultf = atomicExchange(atomf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultd = atomicExchange(buf.datad, resultd);
resultd = atomicExchange(buf.datad, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultd = atomicExchange(atomd, resultd);
resultd = atomicExchange(atomd, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
//atomic load/store
resultf = atomicLoad(buf.dataf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(buf.dataf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultf = atomicLoad(atomf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(atomf, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
resultd = atomicLoad(buf.datad, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(buf.datad, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultd = atomicLoad(atomd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(atomd, resultd, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.datad += resultd;
// image atomics:
atomf = imageAtomicAdd(fimage2D, ivec2(0,0), 2.0);
atomf = imageAtomicAdd(fimage2D, ivec2(1,1), 3.0, gl_ScopeDevice, gl_StorageSemanticsImage , gl_SemanticsRelaxed);
atomf = imageAtomicExchange(fimage2D, ivec2(1,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicLoad(fimage2D, ivec2(1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
imageAtomicStore(fimage2D, ivec2(2,2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
}
#extension GL_EXT_shader_atomic_float: enable
void main()
{
float resultf = 0;
double resultd = 0;
int resulti = 0;
//atomicAdd
resultf = atomicAdd(atomi);
resultf = atomicAdd(atomi, 3.0);
resultf = atomicAdd(atomi, resultf, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
resultf = atomicAdd(atomi, resultf, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelaxed);
//atomicExchange
resultf = atomicExchange(buf.datai);
resultf = atomicExchange(buf.datai, resultf);
resultf = atomicExchange(buf.datai, resultf, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultf = atomicExchange(buf.datai, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
resultf = atomicExchange(atomi, resultf);
resultf = atomicExchange(atomi, resultf, gl_ScopeDevice, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
buf.dataf += resultf;
//atomic load/store
resultf = atomicLoad(buf.datai, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
atomicStore(buf.datai, resulti, gl_StorageSemanticsShared, gl_SemanticsRelaxed);
// image atomics:
atomf = imageAtomicAdd(fimage1D, ivec2(0,0), 2.0);
atomf = imageAtomicAdd(fimage2D, ivec3(0,0,0), 2.0);
atomf = imageAtomicAdd(fimage2D, 2.0);
atomf = imageAtomicExchange(fimage1D, ivec2(1,0), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicExchange(fimage2D, 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicExchange(fimage2D, ivec3(1,0,1), 4.0, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicLoad(fimage1D, ivec2(1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicLoad(fimage2D, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
atomf = imageAtomicLoad(fimage2D, ivec3(1,1,1), gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
imageAtomicStore(fimage1D, ivec2(2,2), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
imageAtomicStore(fimage2D, atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
imageAtomicStore(fimage2D, ivec3(2,2,1), atomf, gl_ScopeDevice, gl_StorageSemanticsImage, gl_SemanticsRelaxed);
buf.dataf += atomf;
}
\ No newline at end of file
...@@ -1241,11 +1241,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ...@@ -1241,11 +1241,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);"
" float atomicAdd(coherent volatile inout float, float);"
" float atomicAdd(coherent volatile inout float, float, int, int, int);"
" double atomicAdd(coherent volatile inout double, double);"
" double atomicAdd(coherent volatile inout double, double, int, int, int);"
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);"
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);" "uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);" " int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);"
" float atomicExchange(coherent volatile inout float, float);"
" float atomicExchange(coherent volatile inout float, float, int, int, int);"
" double atomicExchange(coherent volatile inout double, double);"
" double atomicExchange(coherent volatile inout double, double, int, int, int);"
"uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);" "uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);"
" int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);" " int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);"
...@@ -1254,9 +1262,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ...@@ -1254,9 +1262,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);" "uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
" int64_t atomicLoad(coherent volatile in int64_t, int, int, int);" " int64_t atomicLoad(coherent volatile in int64_t, int, int, int);"
" float atomicLoad(coherent volatile in float, int, int, int);"
" double atomicLoad(coherent volatile in double, int, int, int);"
"void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);" "void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
"void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);" "void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);"
"void atomicStore(coherent volatile out float, float, int, int, int);"
"void atomicStore(coherent volatile out double, double, int, int, int);"
"\n"); "\n");
} }
#endif #endif
...@@ -6013,12 +6025,39 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int ...@@ -6013,12 +6025,39 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
// not int or uint // not int or uint
// GL_ARB_ES3_1_compatibility // GL_ARB_ES3_1_compatibility
// TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers? // TODO: spec issue: are there restrictions on the kind of layout() that can be used? what about dropping memory qualifiers?
if ((profile != EEsProfile && version >= 450) || if (profile == EEsProfile && version >= 310) {
(profile == EEsProfile && version >= 310)) {
commonBuiltins.append("float imageAtomicExchange(volatile coherent "); commonBuiltins.append("float imageAtomicExchange(volatile coherent ");
commonBuiltins.append(imageParams); commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n"); commonBuiltins.append(", float);\n");
} }
if (profile != EEsProfile && version >= 450) {
commonBuiltins.append("float imageAtomicAdd(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n");
commonBuiltins.append("float imageAtomicAdd(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n");
commonBuiltins.append("float imageAtomicExchange(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float);\n");
commonBuiltins.append("float imageAtomicExchange(volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n");
commonBuiltins.append("float imageAtomicLoad(readonly volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", int, int, int);\n");
commonBuiltins.append("void imageAtomicStore(writeonly volatile coherent ");
commonBuiltins.append(imageParams);
commonBuiltins.append(", float");
commonBuiltins.append(", int, int, int);\n");
}
} }
} }
......
...@@ -2110,7 +2110,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan ...@@ -2110,7 +2110,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui) if (imageType.getQualifier().getFormat() != ElfR32i && imageType.getQualifier().getFormat() != ElfR32ui)
error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), ""); error(loc, "only supported on image with format r32i or r32ui", fnCandidate.getName().c_str(), "");
} else { } else {
if (fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0) bool isImageAtomicOnFloatAllowed = ((fnCandidate.getName().compare(0, 14, "imageAtomicAdd") == 0) ||
(fnCandidate.getName().compare(0, 15, "imageAtomicLoad") == 0) ||
(fnCandidate.getName().compare(0, 16, "imageAtomicStore") == 0) ||
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") == 0));
if (imageType.getSampler().type == EbtFloat && isImageAtomicOnFloatAllowed &&
(fnCandidate.getName().compare(0, 19, "imageAtomicExchange") != 0)) // imageAtomicExchange doesn't require GL_EXT_shader_atomic_float
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
if (!isImageAtomicOnFloatAllowed)
error(loc, "only supported on integer images", fnCandidate.getName().c_str(), ""); error(loc, "only supported on integer images", fnCandidate.getName().c_str(), "");
else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile()) else if (imageType.getQualifier().getFormat() != ElfR32f && isEsProfile())
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), ""); error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
...@@ -2139,10 +2146,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan ...@@ -2139,10 +2146,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
if (argp->size() > 3) { if (argp->size() > 3) {
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str()); requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
memorySemanticsCheck(loc, fnCandidate, callNode); memorySemanticsCheck(loc, fnCandidate, callNode);
if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange ||
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpAtomicStore) &&
(arg0->getType().isFloatingDomain())) {
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
}
} else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) { } else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64) {
const char* const extensions[2] = { E_GL_NV_shader_atomic_int64, const char* const extensions[2] = { E_GL_NV_shader_atomic_int64,
E_GL_EXT_shader_atomic_int64 }; E_GL_EXT_shader_atomic_int64 };
requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str()); requireExtensions(loc, 2, extensions, fnCandidate.getName().c_str());
} else if ((callNode.getOp() == EOpAtomicAdd || callNode.getOp() == EOpAtomicExchange) &&
(arg0->getType().isFloatingDomain())) {
requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float, fnCandidate.getName().c_str());
} }
break; break;
} }
......
...@@ -347,6 +347,7 @@ void TParseVersions::initializeExtensionBehavior() ...@@ -347,6 +347,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable; extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable; extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable; extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable;
} }
#endif // GLSLANG_WEB #endif // GLSLANG_WEB
...@@ -520,6 +521,8 @@ void TParseVersions::getPreamble(std::string& preamble) ...@@ -520,6 +521,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_shader_subgroup_extended_types_int16 1\n" "#define GL_EXT_shader_subgroup_extended_types_int16 1\n"
"#define GL_EXT_shader_subgroup_extended_types_int64 1\n" "#define GL_EXT_shader_subgroup_extended_types_int64 1\n"
"#define GL_EXT_shader_subgroup_extended_types_float16 1\n" "#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
"#define GL_EXT_shader_atomic_float 1\n"
; ;
if (version >= 150) { if (version >= 150) {
......
...@@ -298,6 +298,8 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shad ...@@ -298,6 +298,8 @@ const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shad
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64"; const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16"; const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float";
// Arrays of extensions for the above AEP duplications // Arrays of extensions for the above AEP duplications
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
......
...@@ -603,6 +603,8 @@ INSTANTIATE_TEST_CASE_P( ...@@ -603,6 +603,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.460.vert", "spv.460.vert",
"spv.460.comp", "spv.460.comp",
"spv.atomic.comp", "spv.atomic.comp",
"spv.atomicFloat.comp",
"spv.atomicFloat_Error.comp",
"spv.glFragColor.frag", "spv.glFragColor.frag",
"spv.rankShift.comp", "spv.rankShift.comp",
"spv.specConst.vert", "spv.specConst.vert",
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
"site" : "github", "site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools", "subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools", "subdir" : "External/spirv-tools",
"commit" : "a1fb255a2a6856bba1e5a8486469ac93fca518c2" "commit" : "e4aebf99fa14f2cd00026a56b21f7a0cf9940bbd"
}, },
{ {
"name" : "spirv-tools/external/spirv-headers", "name" : "spirv-tools/external/spirv-headers",
"site" : "github", "site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers", "subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers", "subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "ac638f1815425403e946d0ab78bac71d2bdbf3be" "commit" : "979924c8bc839e4cb1b69d03d48398551f369ce7"
} }
] ]
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment