#[compute]
#version 450

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

layout( set = 0, binding = 0 ) 
uniform sampler2D mapping;

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


layout( push_constant, std430 ) 
uniform Parameters 
{
  float maximumLevel;
  float lumaWeightR;
  float lumaWeightG;
  float lumaWeightB;

  float power;
  float scale;
  float maxOutputScale;
  float amount;

} parameters;



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

  vec4 color = imageLoad( outputImage, xy ); 

  float luma = color.r * parameters.lumaWeightR +
               color.g * parameters.lumaWeightG +
               color.b * parameters.lumaWeightB;

  luma = pow( luma, parameters.power ) * parameters.scale;

  
  float lookup = min( 1.0, luma / parameters.maximumLevel );  

  float outputScale = textureLod( mapping, vec2( lookup, 0.0 ), 0 ).r * parameters.maxOutputScale;

  vec4 outputColor = vec4( color.rgb * outputScale / luma, color.a );

  outputColor = mix( color, outputColor, parameters.amount );

  imageStore( outputImage, xy, outputColor );
}