#version 450
#extension GL_KHR_shader_subgroup_basic : require
#extension GL_KHR_shader_subgroup_ballot : require
#extension GL_KHR_shader_subgroup_vote : require

layout(local_size_x = 1) in;

layout(std430, binding = 0) buffer SSBO
{
	float FragColor;
};

void main()
{
	// basic
	FragColor = float(gl_NumSubgroups);
	FragColor = float(gl_SubgroupID);
	FragColor = float(gl_SubgroupSize);
	FragColor = float(gl_SubgroupInvocationID);
	subgroupBarrier();
	subgroupMemoryBarrier();
	subgroupMemoryBarrierBuffer();
	subgroupMemoryBarrierShared();
	subgroupMemoryBarrierImage();
	bool elected = subgroupElect();

	// ballot
	FragColor = float(gl_SubgroupEqMask);
	FragColor = float(gl_SubgroupGeMask);
	FragColor = float(gl_SubgroupGtMask);
	FragColor = float(gl_SubgroupLeMask);
	FragColor = float(gl_SubgroupLtMask);
	vec4 broadcasted = subgroupBroadcast(vec4(10.0), 8u);
	vec3 first = subgroupBroadcastFirst(vec3(20.0));
	uvec4 ballot_value = subgroupBallot(true);
	bool inverse_ballot_value = subgroupInverseBallot(ballot_value);
	bool bit_extracted = subgroupBallotBitExtract(uvec4(10u), 8u);
	uint bit_count = subgroupBallotBitCount(ballot_value);
	uint inclusive_bit_count = subgroupBallotInclusiveBitCount(ballot_value);
	uint exclusive_bit_count = subgroupBallotExclusiveBitCount(ballot_value);
	uint lsb = subgroupBallotFindLSB(ballot_value);
	uint msb = subgroupBallotFindMSB(ballot_value);

	// vote
	bool has_all = subgroupAll(true);
	bool has_any = subgroupAny(true);
	bool has_equal_bool = subgroupAllEqual(true);
	bool has_equal_T = subgroupAllEqual(uvec3(5u));
}