/*
 * bilinear low res scaling, samples 8 pixels of a larger image to scale to a
 * low resolution image below half size
 */

#include "color.effect"

uniform float4x4 ViewProj;
uniform texture2d image;
uniform float multiplier;

sampler_state textureSampler {
	Filter    = Linear;
	AddressU  = Clamp;
	AddressV  = Clamp;
};

struct VertData {
	float4 pos : POSITION;
	float2 uv  : TEXCOORD0;
};

VertData VSDefault(VertData v_in)
{
	VertData vert_out;
	vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj);
	vert_out.uv  = v_in.uv;
	return vert_out;
}

float4 pixel(float2 uv)
{
	return image.Sample(textureSampler, uv);
}

float4 DrawLowresBilinear(VertData f_in)
{
	float2 uv = f_in.uv;
	float2 stepxy  = float2(ddx(uv.x), ddy(uv.y));
	float2 stepxy1 = stepxy * 0.0625;
	float2 stepxy3 = stepxy * 0.1875;
	float2 stepxy5 = stepxy * 0.3125;
	float2 stepxy7 = stepxy * 0.4375;

	// Simulate Direct3D 8-sample pattern
	float4 out_color;
	out_color  = pixel(uv + float2( stepxy1.x, -stepxy3.y));
	out_color += pixel(uv + float2(-stepxy1.x,  stepxy3.y));
	out_color += pixel(uv + float2( stepxy5.x,  stepxy1.y));
	out_color += pixel(uv + float2(-stepxy3.x, -stepxy5.y));
	out_color += pixel(uv + float2(-stepxy5.x,  stepxy5.y));
	out_color += pixel(uv + float2(-stepxy7.x, -stepxy1.y));
	out_color += pixel(uv + float2( stepxy3.x,  stepxy7.y));
	out_color += pixel(uv + float2( stepxy7.x, -stepxy7.y));
	return out_color * 0.125;
}

float4 PSDrawLowresBilinearRGBA(VertData f_in) : TARGET
{
	return DrawLowresBilinear(f_in);
}

float4 PSDrawLowresBilinearRGBAMultiply(VertData f_in) : TARGET
{
	float4 rgba = DrawLowresBilinear(f_in);
	rgba.rgb *= multiplier;
	return rgba;
}

float4 PSDrawLowresBilinearRGBATonemap(VertData f_in) : TARGET
{
	float4 rgba = DrawLowresBilinear(f_in);
	rgba.rgb = rec709_to_rec2020(rgba.rgb);
	rgba.rgb = reinhard(rgba.rgb);
	rgba.rgb = rec2020_to_rec709(rgba.rgb);
	return rgba;
}

float4 PSDrawLowresBilinearRGBAMultiplyTonemap(VertData f_in) : TARGET
{
	float4 rgba = DrawLowresBilinear(f_in);
	rgba.rgb *= multiplier;
	rgba.rgb = rec709_to_rec2020(rgba.rgb);
	rgba.rgb = reinhard(rgba.rgb);
	rgba.rgb = rec2020_to_rec709(rgba.rgb);
	return rgba;
}

float4 PSDrawLowresBilinearRGBADivide(VertData f_in) : TARGET
{
	float4 rgba = DrawLowresBilinear(f_in);
	rgba.rgb *= max(1. / rgba.a, 0.);
	return rgba;
}

technique Draw
{
	pass
	{
		vertex_shader = VSDefault(v_in);
		pixel_shader  = PSDrawLowresBilinearRGBA(f_in);
	}
}

technique DrawMultiply
{
	pass
	{
		vertex_shader = VSDefault(v_in);
		pixel_shader  = PSDrawLowresBilinearRGBAMultiply(f_in);
	}
}

technique DrawTonemap
{
	pass
	{
		vertex_shader = VSDefault(v_in);
		pixel_shader  = PSDrawLowresBilinearRGBATonemap(f_in);
	}
}

technique DrawMultiplyTonemap
{
	pass
	{
		vertex_shader = VSDefault(v_in);
		pixel_shader  = PSDrawLowresBilinearRGBAMultiplyTonemap(f_in);
	}
}

technique DrawAlphaDivide
{
	pass
	{
		vertex_shader = VSDefault(v_in);
		pixel_shader  = PSDrawLowresBilinearRGBADivide(f_in);
	}
}
