#[compute]
#version 450

layout( local_size_x = 8, local_size_y = 8, local_size_z = 1 ) in;

layout( rgba16f, set = 0, binding = 0 ) 
uniform image2D inputImage;

layout( rgba16f, set = 1, binding = 0 ) 
uniform image2D outputImage;


layout( push_constant, std430 ) 
uniform Parameters 
{
  float amount;

  float k00;
  float k01;
  float k02;

  float k10;
  float k11;
  float k12;

  float k20;
  float k21;
  float k22;

  float kernelOffset;

  float clampValues;

} parameters;

vec4 getPixel( ivec2 pixelUV, int x, int y, int kernelOffset, ivec2 size )
{
  ivec2 xy = ivec2( x, y ) * kernelOffset;
  ivec2 kernelUV = pixelUV + xy;

  kernelUV.x = clamp( kernelUV.x, 0, size.x - 1 );
  kernelUV.y = clamp( kernelUV.y, 0, size.y - 1 );

  return imageLoad( inputImage, kernelUV );
}

void main( ) 
{
  ivec2 size = imageSize( inputImage );
  ivec2 pixelUV = ivec2( gl_GlobalInvocationID.xy );
  
  if ( any( greaterThanEqual( pixelUV, size ) )  ) 
  {
    return;
  }

  vec4 color = vec4( 0.0 );

  int kernelOffsetInt = int( parameters.kernelOffset );

  color += parameters.k00 * getPixel( pixelUV, -1, -1, kernelOffsetInt, size );
  color += parameters.k01 * getPixel( pixelUV, -1,  0, kernelOffsetInt, size );
  color += parameters.k02 * getPixel( pixelUV, -1,  1, kernelOffsetInt, size );

  color += parameters.k10 * getPixel( pixelUV,  0, -1, kernelOffsetInt, size );
  color += parameters.k11 * getPixel( pixelUV,  0,  0, kernelOffsetInt, size );
  color += parameters.k12 * getPixel( pixelUV,  0,  1, kernelOffsetInt, size );

  color += parameters.k20 * getPixel( pixelUV,  1, -1, kernelOffsetInt, size );
  color += parameters.k21 * getPixel( pixelUV,  1,  0, kernelOffsetInt, size );
  color += parameters.k22 * getPixel( pixelUV,  1,  1, kernelOffsetInt, size ); 

  if ( parameters.clampValues > 0.5 )
  {
    color = clamp( color, 0.0, 1.0 );
  }

  vec4 originalColor = imageLoad( inputImage, pixelUV );

  vec4 mixedColor = mix( originalColor, color, parameters.amount );

  imageStore( outputImage, pixelUV, mixedColor );
}