// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.

namespace Stride.Rendering.Compositing
{
    /// <summary>
    /// A MSAA depth textures resolver shader
    /// </summary>
    internal shader MSAADepthResolverShader : ShaderBase, Texturing, Math
    {
        stage stream float4 Position : POSITION;

        stage float4 SvPosUnpack;
        stage float2 TextureSizeLess1;

#ifndef INPUT_MSAA_SAMPLES
		stage Texture2DMS<float4> InputTexture;
#elif INPUT_MSAA_SAMPLES == 1
		stage Texture2DMS<float4, 1> InputTexture;
#elif INPUT_MSAA_SAMPLES == 2
		stage Texture2DMS<float4, 2> InputTexture;
#elif INPUT_MSAA_SAMPLES == 4
		stage Texture2DMS<float4, 4> InputTexture;
#elif INPUT_MSAA_SAMPLES == 8
		stage Texture2DMS<float4, 8> InputTexture;
#else
        #error "Unsupported amount of MSAA texture samples."
#endif

		// 1:-1 to 0:TextureSize
        int2 ClipPosToUvPos(float2 clipPos)
        {
            return (int2)(clipPos * SvPosUnpack.xy + SvPosUnpack.zw);
        }

        stage override void VSMain()
        {
            streams.ShadingPosition = streams.Position;
        }

        override stage void PSMain()
        {
            float4 output = 0;
			int2 pixelPos = ClipPosToUvPos(streams.Position.xy);

            float resolvedDepth = InputTexture.Load(pixelPos, 0).r;

#ifdef INPUT_MSAA_SAMPLES
            
            // Get the closest depth value
            [unroll]
            for (int sampleIndex = 1; sampleIndex < INPUT_MSAA_SAMPLES; sampleIndex++)
            {
                float sampleDepth = InputTexture.Load(pixelPos, sampleIndex).r;
                resolvedDepth = min(resolvedDepth, sampleDepth);
            }

#endif

            streams.Depth = resolvedDepth;
        }
    };
}
