#version 430 compatibility
#extension GL_ARB_compute_shader : enable
#extension GL_ARB_shader_image_load_store : enable
#extension GL_ARB_shader_storage_buffer_object : enable
uniform vec2 ImageSize;
layout(binding=0, rgba8ui) uniform readonly uimage2D Texture;
layout(binding=1, rgba8ui) uniform uimage2D GlobalHistograms;
layout(std140, binding=0) buffer blocks {
double result;
};
layout (local_size_x = 45, local_size_y = 1, local_size_z = 1) in;
shared uint histogram[3][256];
void main(void)
{
uint totalSize = gl_WorkGroupSize.x * gl_WorkGroupSize.y * gl_WorkGroupSize.z/(gl_NumWorkGroups.x*gl_NumWorkGroups.y*gl_NumWorkGroups.z);
uint index = gl_LocalInvocationIndex;
uvec2 size = uvec2(ImageSize);
start = index * size.y / totalSize;
end = (index+1) * size.y / totalSize;
if (index == totalSize-1)
end = uint(ImageSize.y);
for (uint i = start; i < end; ++i)
{
for (uint j = 0; j < size.x; ++j)
{
ivec2 position = ivec2(j, i);
uvec4 color = imageLoad(Texture, position);
atomicAdd(histogram[0][color.r], 1);
atomicAdd(histogram[1][color.g], 1);
atomicAdd(histogram[2][color.b], 1);
}
}
barrier();
if (index == 0)
{
for (uint i = 0; i < 256; ++i)
{
imageAtomicAdd(GlobalHistograms, ivec(0, i), histogram[0][i]);
imageAtomicAdd(GlobalHistograms, ivec(1, i), histogram[1][i]);
imageAtomicAdd(GlobalHistograms, ivec(2, i), histogram[2][i]);
}
}
}