diff --git a/Test/420.frag b/Test/420.frag index 1444758eaa..93a14de9a6 100644 --- a/Test/420.frag +++ b/Test/420.frag @@ -12,3 +12,31 @@ layout(depth_less) in float depth; // ERROR: depth_less only applies to gl_FragD layout(depth_any) out float gl_FragDepth; // ERROR, done after use layout(binding=0) uniform atomic_uint a[]; + +#extension GL_ARB_shader_storage_buffer_object : enable + +layout(binding = 0,std430) buffer Buffer +{ + int atomi; + uint atomu; +}; + +void atomicOpPass() +{ + int origi = atomicAdd(atomi, 3); + uint origu = atomicAnd(atomu, 7u); + origi = atomicExchange(atomi, 4); + origu = atomicCompSwap(atomu, 10u, 8u); +} + +#extension GL_ARB_shader_storage_buffer_object : disable + +layout(binding = 1,std430) buffer BufferFail // Error std430 and "buffer" block support disabled +{ + int atom1i; +}; + +void atomicOpFail() +{ + int origi = atomicAdd(atom1i, 3); // Error, atomic operations disabled +} diff --git a/Test/baseResults/420.frag.out b/Test/baseResults/420.frag.out index ffb8f6d283..48bbf36b6d 100644 --- a/Test/baseResults/420.frag.out +++ b/Test/baseResults/420.frag.out @@ -3,10 +3,14 @@ ERROR: 0:4: 'redeclaration' : all redeclarations must use the same depth layout ERROR: 0:11: 'layout qualifier' : can only apply depth layout to gl_FragDepth ERROR: 0:12: 'gl_FragDepth' : cannot redeclare after use ERROR: 0:14: 'atomic_uint' : array must be explicitly sized -ERROR: 4 compilation errors. No code generated. +ERROR: 0:34: 'std430' : not supported for this version or the enabled extensions +ERROR: 0:34: 'buffer block' : not supported for this version or the enabled extensions +ERROR: 0:41: 'atomicAdd' : required extension not requested: GL_ARB_shader_storage_buffer_object +ERROR: 7 compilation errors. No code generated. Shader version: 420 +Requested GL_ARB_shader_storage_buffer_object using depth_any ERROR: node is still EOpNull! 0:6 Function Definition: main( ( global void) @@ -16,16 +20,75 @@ ERROR: node is still EOpNull! 0:8 'gl_FragDepth' ( gl_FragDepth float FragDepth) 0:8 Constant: 0:8 0.300000 +0:24 Function Definition: atomicOpPass( ( global void) +0:24 Function Parameters: +0:26 Sequence +0:26 Sequence +0:26 move second child to first child ( temp int) +0:26 'origi' ( temp int) +0:26 AtomicAdd ( global int) +0:26 atomi: direct index for structure (layout( column_major std430 offset=0) buffer int) +0:26 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:26 Constant: +0:26 0 (const uint) +0:26 Constant: +0:26 3 (const int) +0:27 Sequence +0:27 move second child to first child ( temp uint) +0:27 'origu' ( temp uint) +0:27 AtomicAnd ( global uint) +0:27 atomu: direct index for structure (layout( column_major std430 offset=4) buffer uint) +0:27 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:27 Constant: +0:27 1 (const uint) +0:27 Constant: +0:27 7 (const uint) +0:28 move second child to first child ( temp int) +0:28 'origi' ( temp int) +0:28 AtomicExchange ( global int) +0:28 atomi: direct index for structure (layout( column_major std430 offset=0) buffer int) +0:28 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:28 Constant: +0:28 0 (const uint) +0:28 Constant: +0:28 4 (const int) +0:29 move second child to first child ( temp uint) +0:29 'origu' ( temp uint) +0:29 AtomicCompSwap ( global uint) +0:29 atomu: direct index for structure (layout( column_major std430 offset=4) buffer uint) +0:29 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:29 Constant: +0:29 1 (const uint) +0:29 Constant: +0:29 10 (const uint) +0:29 Constant: +0:29 8 (const uint) +0:39 Function Definition: atomicOpFail( ( global void) +0:39 Function Parameters: +0:41 Sequence +0:41 Sequence +0:41 move second child to first child ( temp int) +0:41 'origi' ( temp int) +0:41 AtomicAdd ( global int) +0:41 atom1i: direct index for structure (layout( column_major std430 offset=0) buffer int) +0:41 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atom1i}) +0:41 Constant: +0:41 0 (const uint) +0:41 Constant: +0:41 3 (const int) 0:? Linker Objects 0:? 'gl_FragDepth' ( gl_FragDepth float FragDepth) 0:? 'depth' ( smooth in float) 0:? 'a' (layout( binding=0 offset=0) uniform unsized 1-element array of atomic_uint) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:? 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atom1i}) Linked fragment stage: Shader version: 420 +Requested GL_ARB_shader_storage_buffer_object using depth_any ERROR: node is still EOpNull! 0:6 Function Definition: main( ( global void) @@ -39,4 +102,6 @@ ERROR: node is still EOpNull! 0:? 'gl_FragDepth' ( gl_FragDepth float FragDepth) 0:? 'depth' ( smooth in float) 0:? 'a' (layout( binding=0 offset=0) uniform 1-element array of atomic_uint) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atomi, layout( column_major std430 offset=4) buffer uint atomu}) +0:? 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430 offset=0) buffer int atom1i}) diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 32106c7dd8..308a58c9a9 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -153,6 +153,11 @@ EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECo { EBadProfile } }; const Versioning* Es300Desktop130 = &Es300Desktop130Version[0]; + const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr }, + { EDesktopProfile, 0, 420, 0, nullptr }, + { EBadProfile } }; + const Versioning* Es310Desktop420 = &Es310Desktop420Version[0]; + const Versioning Es310Desktop430Version[] = { { EEsProfile, 0, 310, 0, nullptr }, { EDesktopProfile, 0, 430, 0, nullptr }, { EBadProfile } }; @@ -256,14 +261,14 @@ const BuiltInFunction BaseFunctions[] = { { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, { EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 }, { EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop430 }, - { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop430 }, + { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, + { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 }, #ifndef GLSLANG_WEB { EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 }, { EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 }, @@ -7823,6 +7828,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); } + // GL_ARB_shader_storage_buffer_object + if (profile != EEsProfile && version < 430 ) { + symbolTable.setFunctionExtensions("atomicAdd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMin", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicMax", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicAnd", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicOr", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicXor", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicExchange", 1, &E_GL_ARB_shader_storage_buffer_object); + symbolTable.setFunctionExtensions("atomicCompSwap", 1, &E_GL_ARB_shader_storage_buffer_object); + } + symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index f954802dcb..d3c9269caf 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -4899,7 +4899,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi #ifndef GLSLANG_WEB if (id == TQualifier::getLayoutPackingString(ElpStd430)) { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "std430"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430"); profileRequires(loc, EEsProfile, 310, nullptr, "std430"); publicType.qualifier.layoutPacking = ElpStd430; return; @@ -7669,7 +7669,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q break; case EvqBuffer: requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); - profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "buffer block"); profileRequires(loc, EEsProfile, 310, nullptr, "buffer block"); break; case EvqVaryingIn: diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index 656daaf2cf..f222e5dcdd 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -917,7 +917,7 @@ int TScanContext::tokenizeIdentifier() case BUFFER: afterBuffer = true; if ((parseContext.isEsProfile() && parseContext.version < 310) || - (!parseContext.isEsProfile() && parseContext.version < 430)) + (!parseContext.isEsProfile() && parseContext.version < 420)) return identifierOrType(); return keyword; diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 2da1dbc67f..6e77056006 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -198,6 +198,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable; extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable; extensionBehavior[E_GL_ARB_shader_bit_encoding] = EBhDisable; + extensionBehavior[E_GL_ARB_shader_storage_buffer_object] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable; extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable; @@ -411,6 +412,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_fragment_shader_interlock 1\n" "#define GL_ARB_uniform_buffer_object 1\n" "#define GL_ARB_shader_bit_encoding 1\n" + "#define GL_ARB_shader_storage_buffer_object 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_post_depth_coverage 1\n" diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index f9ab2e2fd5..befb5dcd7a 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -153,6 +153,7 @@ const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock"; const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object"; const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading"; const char* const E_GL_ARB_shader_bit_encoding = "GL_ARB_shader_bit_encoding"; +const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage_buffer_object"; const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic"; const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";