#pragma clang diagnostic ignored "-Wmissing-prototypes"
#pragma clang diagnostic ignored "-Wmissing-braces"

#include <metal_stdlib>
#include <simd/simd.h>

using namespace metal;

template<typename T, size_t Num>
struct spvUnsafeArray
{
    T elements[Num ? Num : 1];
    
    thread T& operator [] (size_t pos) thread
    {
        return elements[pos];
    }
    constexpr const thread T& operator [] (size_t pos) const thread
    {
        return elements[pos];
    }
    
    device T& operator [] (size_t pos) device
    {
        return elements[pos];
    }
    constexpr const device T& operator [] (size_t pos) const device
    {
        return elements[pos];
    }
    
    constexpr const constant T& operator [] (size_t pos) const constant
    {
        return elements[pos];
    }
    
    threadgroup T& operator [] (size_t pos) threadgroup
    {
        return elements[pos];
    }
    constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
    {
        return elements[pos];
    }
};

struct Uniforms
{
    float4x4 projection;
    float dpi_scale;
    uint mode;
    float2 _pad0;
};

struct Gaussian_Blur_Primitive
{
    float4 bounds;
    float4 radii_ppx;
    float2 half_size_ppx;
    float half_feather_ppx;
    uint color;
};

struct Gaussian_Blur_Primitive_1
{
    float4 bounds;
    float4 radii_ppx;
    float2 half_size_ppx;
    float half_feather_ppx;
    uint color;
};

struct Gaussian_Blur_Primitives
{
    Gaussian_Blur_Primitive_1 primitives[1];
};

constant spvUnsafeArray<float2, 6> _97 = spvUnsafeArray<float2, 6>({ float2(0.0), float2(1.0, 0.0), float2(0.0, 1.0), float2(0.0, 1.0), float2(1.0, 0.0), float2(1.0) });

struct main0_out
{
    float2 p_local [[user(locn0)]];
    float4 f_color [[user(locn1)]];
    float2 f_half_size_ppx [[user(locn2)]];
    float4 f_radii_ppx [[user(locn3)]];
    float f_half_feather_ppx [[user(locn4)]];
    float4 gl_Position [[position]];
};

vertex main0_out main0(constant Uniforms& _13 [[buffer(0)]], const device Gaussian_Blur_Primitives& _69 [[buffer(1)]], uint gl_VertexIndex [[vertex_id]], uint gl_InstanceIndex [[instance_id]])
{
    main0_out out = {};
    if (_13.mode == 0u)
    {
        float2 ndc = float2((int(gl_VertexIndex) == 1) ? 3.0 : (-1.0), (int(gl_VertexIndex) == 2) ? 3.0 : (-1.0));
        out.gl_Position = float4(ndc, 0.0, 1.0);
        out.p_local = float2(0.0);
        out.f_color = float4(0.0);
        out.f_half_size_ppx = float2(0.0);
        out.f_radii_ppx = float4(0.0);
        out.f_half_feather_ppx = 0.0;
    }
    else
    {
        Gaussian_Blur_Primitive p;
        p.bounds = _69.primitives[int(gl_InstanceIndex)].bounds;
        p.radii_ppx = _69.primitives[int(gl_InstanceIndex)].radii_ppx;
        p.half_size_ppx = _69.primitives[int(gl_InstanceIndex)].half_size_ppx;
        p.half_feather_ppx = _69.primitives[int(gl_InstanceIndex)].half_feather_ppx;
        p.color = _69.primitives[int(gl_InstanceIndex)].color;
        float2 corner = _97[int(gl_VertexIndex)];
        float2 world_pos = mix(p.bounds.xy, p.bounds.zw, corner);
        float2 center = (p.bounds.xy + p.bounds.zw) * 0.5;
        out.p_local = (world_pos - center) * _13.dpi_scale;
        out.f_color = unpack_unorm4x8_to_float(p.color);
        out.f_half_size_ppx = p.half_size_ppx;
        out.f_radii_ppx = p.radii_ppx;
        out.f_half_feather_ppx = p.half_feather_ppx;
        out.gl_Position = _13.projection * float4(world_pos * _13.dpi_scale, 0.0, 1.0);
    }
    return out;
}

