#version 450
 #extension GL_EXT_multiview : enable
// Vk3DVision SinglePass
///////////////////////////////////////////////////////////////////////////////

#define STEREO 1


#define VIEW gl_WorkGroupID.z / (gl_NumWorkGroups.z /2)
#define NumWorkGroups uvec3(gl_NumWorkGroups.x, gl_NumWorkGroups.y, gl_NumWorkGroups.z / 2)
#define WorkGroupID uvec3(gl_WorkGroupID.x, gl_WorkGroupID.y, (gl_WorkGroupID.z < (gl_WorkGroupID.z + 1) / 2 ? gl_WorkGroupID.z : gl_WorkGroupID.z - (gl_WorkGroupID.z + 1) / 2))
#define GlobalInvocationID uvec3(WorkGroupID * gl_WorkGroupSize + gl_LocalInvocationID)

// Stereo and Mono Texture Sampling
#if(STEREO == 1)
	#define SAMPLER_2D sampler2DArray
	#define USAMPLER_2D usampler2DArray
	#define ISAMPLER_2D isampler2DArray
	#define IMAGE_2D image2DArray
	#define UIMAGE_2D uimage2DArray
	#define UTEXTURE_2D utexture2DArray
	#define TEXTURE_2D texture2DArray
	#define SAMPLE_TEXTURE(Sampler, uv) texture(Sampler, vec3(uv, VIEW))
	#define SAMPLE_TEXTURE1(Sampler, uv, bias) texture(Sampler, vec3(uv, VIEW), bias)
	#define IMAGE_LOAD(Image2D, pos) imageLoad(Image2D, ivec3(pos, VIEW))
	#define IMAGE_STORE(Image2D, pos, result) imageStore(Image2D, ivec3(pos, VIEW), result)
	#define TEXEL_FETCH(Sampler, uv, lod) texelFetch(Sampler, ivec3(uv, VIEW), lod)
	#define TEXEL_FETCH_OFFSET(Sampler, uv, lod, offset) texelFetchOffset(Sampler, ivec3(uv, VIEW), lod, offset)
	#define TEXTURE_LOD(Sampler, uv, lod) textureLod(Sampler, vec3(uv, VIEW), lod)
	#define TEXTURE_LOD_OFFSET(Sampler, uv, lod, offset) textureLodOffset(Sampler, vec3(uv, VIEW), lod, offset)
	#define TEXTURE_GATHER(Sampler, uv, comp) textureGather(Sampler, vec3(uv, VIEW), comp)
	#define TEXTURE_GATHER1(Sampler, uv) textureGather(Sampler, vec3(uv, VIEW))
	#define TEXTURE_GATHER_OFFSET(Sampler, uv, offset, comp) textureGatherOffset(Sampler, vec3(uv, VIEW), offset, comp)
	#define TEXTURE_GATHER_OFFSETS(Sampler, uv, offset) textureGatherOffsets(Sampler, vec3(uv, VIEW), offset)
	#define TEXTURE_GATHER_OFFSETS1(Sampler, uv, offset, comp) textureGatherOffsets(Sampler, vec3(uv, VIEW), offset, comp)
	#define TEXTURE_SIZE(Sampler, lod) textureSize(Sampler, lod).xy
	#define TEXTURE_GRAD(Sampler, P, dPdx, dPdy) textureGrad(Sampler, vec3(P, VIEW), dPdx, dPdy)
#else
	#define SAMPLER_2D sampler2D
	#define USAMPLER_2D usampler2D
	#define ISAMPLER_2D isampler2D
	#define IMAGE_2D image2D
	#define UIMAGE_2D uimage2D
	#define UTEXTURE_2D utexture2D
	#define TEXTURE_2D texture2D
	#define SAMPLE_TEXTURE(Sampler, uv) texture(Sampler, uv)
	#define SAMPLE_TEXTURE1(Sampler, uv, bias) texture(Sampler, uv, bias)
	#define IMAGE_LOAD(Image2D, pos) imageLoad(Image2D, pos)
	#define IMAGE_STORE(Image2D, pos, result) imageStore(Image2D, pos, result)
	#define TEXEL_FETCH(Sampler, uv, lod) texelFetch(Sampler, uv, lod)
	#define TEXEL_FETCH_OFFSET(Sampler, uv, lod, offset) texelFetchOffset(Sampler, uv, lod, offset)
	#define TEXTURE_LOD(Sampler, uv, lod) textureLod(Sampler, uv, lod)
	#define TEXTURE_LOD_OFFSET(Sampler, uv, lod, offset) textureLodOffset(Sampler, uv, lod, offset)
	#define TEXTURE_GATHER(Sampler, uv, comp) textureGather(Sampler, uv, comp)
	#define TEXTURE_GATHER1(Sampler, uv, comp) textureGather(Sampler, uv)
	#define TEXTURE_GATHER_OFFSET(Sampler, uv, offset, comp) textureGatherOffset(Sampler, uv, offset, comp)
	#define TEXTURE_GATHER_OFFSETS(Sampler, uv, offset) textureGatherOffsets(Sampler, uv, offset)
	#define TEXTURE_GATHER_OFFSETS1(Sampler, uv, offset, comp) textureGatherOffsets(Sampler, uv, offset, comp)
	#define TEXTURE_SIZE(Sampler, lod) textureSize(Sampler, lod)
	#define TEXTURE_GRAD(Sampler, P, dPdx, dPdy) textureGrad(Sampler, P, dPdx, dPdy)
#endif 
 ///////////////////////////////////////////////////////////////////////////////
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;


// Vk3DVision (http://3dsurroundgaming.com/) - Stereo Injection
struct Vk3DStereo
{
	vec4 stereo;
	vec4 custom_params;
};
layout(set = 0, binding = 10, std140) uniform Vk3DParams
{
	Vk3DStereo vk3d_params[2];
};

layout(set = 1, binding = 0, std140) uniform _195_197
{
    vec4 _m0;
    vec4 _m1;
} _197;

layout(set = 0, binding = 0, std140) uniform _206_208
{
    vec4 _m0;
    vec4 _m1;
    vec4 _m2;
    vec4 _m3;
    vec4 _m4;
    vec4 _m5;
    vec4 _m6;
    vec4 _m7;
    vec4 _m8;
    vec4 _m9;
    vec4 _m10;
    vec4 _m11;
} _208;

layout(push_constant, std430) uniform _509_511
{
    int _m0;
    int _m1;
} _511;

layout(set = 0, binding = 1) uniform SAMPLER_2D _117;
layout(set = 1, binding = 1) uniform SAMPLER_2D _342;
layout(set = 1, binding = 2) uniform SAMPLER_2D _367;
layout(set = 1, binding = 3) uniform SAMPLER_2D _451;
layout(set = 1, binding = 4, r11f_g11f_b10f) uniform writeonly IMAGE_2D _487;
layout(set = 1, binding = 5, rg16f) uniform writeonly IMAGE_2D _500;

vec3 _430;

vec4 _24(SAMPLER_2D _21, ivec2 _22, int _23)
{
    return TEXEL_FETCH(_21, _22, _23);
}

float _42(float _38, vec4 _39, float _40, bool _41)
{
    float _103 = _39.w / (_38 + _39.z);
    return _103 * _40;
}

vec3 _47(inout vec2 _46)
{
    const ivec2 offsets[4] = {ivec2(0,0), ivec2(0,0), ivec2(0,0), ivec2(0,0)};
    vec4 _116 = TEXTURE_GATHER_OFFSETS(_117, _46, offsets);
    vec3 _132 = vec3(vec2(-1.0), _116.x);
    vec3 _147;
    if (_116.y < _132.z)
    {
        _147 = vec3(vec2(1.0, -1.0), _116.y);
    }
    else
    {
        _147 = _132;
    }
    _132 = _147;
    vec3 _164;
    if (_116.z < _132.z)
    {
        _164 = vec3(vec2(-1.0, 1.0), _116.z);
    }
    else
    {
        _164 = _132;
    }
    _132 = _164;
    vec3 _181;
    if (_116.w < _132.z)
    {
        _181 = vec3(vec2(1.0), _116.w);
    }
    else
    {
        _181 = _132;
    }
    _132 = _181;
    _46 += (_132.xy * _197._m0.zw);
    float _210 = _132.z;
    vec4 _213 = _208._m0;
    float _216 = 1.0;
    bool _217 = true;
    float _205 = _42(_210, _213, _216, _217);
    vec3 _219 = mix(_208._m1.xyz, _208._m2.xyz, vec3(_46.x * _208._m3.z));
    vec3 _236 = mix(_208._m4.xyz, _208._m5.xyz, vec3(_46.x * _208._m3.z));
    vec3 _252 = mix(_236, _219, vec3(1.0 - (_46.y * _208._m3.w)));
    vec3 _263 = _208._m6.xyz + (_252 * _205);
    float _272 = 1.0 / ((_263.x * _208._m7.x) + ((_263.y * _208._m7.y) + ((_263.z * _208._m7.z) + _208._m7.w)));
    vec2 _295 = vec2((_263.x * _208._m8.x) + ((_263.y * _208._m8.y) + ((_263.z * _208._m8.z) + _208._m8.w)), (_263.x * _208._m9.x) + ((_263.y * _208._m9.y) + ((_263.z * _208._m9.z) + _208._m9.w))) * _272;
    vec2 _341 = TEXTURE_LOD(_342, vec4(_46, 0.0, 0.0).xy, vec4(_46, 0.0, 0.0).w).xy;
    float _356 = _132.z;
    if (_208._m10.x == 1.0)
    {
        uint _366 = uint(TEXTURE_LOD(_367, vec4(_46, 0.0, 0.0).xy, vec4(_46, 0.0, 0.0).w).w * 255.0);
        vec2 _390;
        if (((_366 & 4u) != 0u) && (_356 < 1.0))
        {
            _390 = _341;
        }
        else
        {
            _390 = _46 - (_295 * _208._m3.xy);
        }
        return vec3(_390, _205);
    }
    else
    {
        vec2 _412;
        if (_341.x < 1.0)
        {
            _412 = _341;
        }
        else
        {
            _412 = _46 - (_295 * _208._m3.xy);
        }
        return vec3(_412, _205);
    }
}

float _10(float _9)
{
    return clamp(_9, 0.0, 1.0);
}

vec4 _33(vec4 _30, inout vec2 _31, float _32)
{
    vec2 _62 = _31;
    float _64 = 1.0;
    _31 *= (_30.z * _64);
    float _73 = inversesqrt(dot(_31, _31));
    float _83 = _30.w * _73;
    _31 *= _10(_83);
    _31 *= _30.xy;
    return vec4(_62, vec2(length(_31), _32));
}

void main()
{
    ivec3 _433 = ivec3(GlobalInvocationID);
    vec2 _439 = (vec2(_433.xy) + vec2(0.5)) * _197._m1.zw;
    ivec2 _452 = _433.xy;
    int _455 = 0;
    vec3 _450 = _24(_451, _452, _455).xyz;
    vec2 _459 = _439;
    vec3 _461 = _47(_459);
    vec3 _458 = _461;
    vec3 _462 = max(vec3(0.0), _450);
    vec4 _468 = _208._m11;
    vec2 _471 = _458.xy;
    float _474 = _458.z;
    vec4 _477 = _33(_468, _471, _474);
    vec3 _466;
    _466 = vec3(_477.zw.x, _477.zw.y, _466.z);
    _466.x = 1.0 / _466.x;
    IMAGE_STORE(_487, _433.xy, vec4(_462.x, _462.y, _462.z, 0.0));
    IMAGE_STORE(_500, _433.xy, vec4(_466.x, _466.y, 0.0, 0.0));
}

