#version 450
#if defined(GL_AMD_gpu_shader_half_float)
#extension GL_AMD_gpu_shader_half_float : require
#elif defined(GL_EXT_shader_explicit_arithmetic_types_float16)
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
#else
#error No extension available for FP16.
#endif
#extension GL_EXT_shader_16bit_storage : require
#extension GL_EXT_spirv_intrinsics : require

layout(location = 0) in vec4 A;
layout(location = 1) in vec4 B;
layout(location = 2) in vec4 C;
layout(location = 0) out vec4 SV_Target;

spirv_instruction(set = "GLSL.std.450", id = 81) float16_t spvNClamp(float16_t, float16_t, float16_t);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec2 spvNClamp(f16vec2, f16vec2, f16vec2);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec3 spvNClamp(f16vec3, f16vec3, f16vec3);
spirv_instruction(set = "GLSL.std.450", id = 81) f16vec4 spvNClamp(f16vec4, f16vec4, f16vec4);
spirv_instruction(set = "GLSL.std.450", id = 81) float spvNClamp(float, float, float);
spirv_instruction(set = "GLSL.std.450", id = 81) vec2 spvNClamp(vec2, vec2, vec2);
spirv_instruction(set = "GLSL.std.450", id = 81) vec3 spvNClamp(vec3, vec3, vec3);
spirv_instruction(set = "GLSL.std.450", id = 81) vec4 spvNClamp(vec4, vec4, vec4);
spirv_instruction(set = "GLSL.std.450", id = 81) double spvNClamp(double, double, double);
spirv_instruction(set = "GLSL.std.450", id = 81) dvec2 spvNClamp(dvec2, dvec2, dvec2);
spirv_instruction(set = "GLSL.std.450", id = 81) dvec3 spvNClamp(dvec3, dvec3, dvec3);
spirv_instruction(set = "GLSL.std.450", id = 81) dvec4 spvNClamp(dvec4, dvec4, dvec4);

void main()
{
    SV_Target.x = float(spvNClamp(double(A.x), double(B.x), double(C.x)) + double(float(spvNClamp(float16_t(A.x), float16_t(B.x), float16_t(C.x))) + spvNClamp(A.x, B.x, C.x)));
    SV_Target.y = float(spvNClamp(double(A.y), double(B.y), double(C.y)) + double(float(spvNClamp(float16_t(A.y), float16_t(B.y), float16_t(C.y))) + spvNClamp(A.y, B.y, C.y)));
    SV_Target.z = float(spvNClamp(double(A.z), double(B.z), double(C.z)) + double(float(spvNClamp(float16_t(A.z), float16_t(B.z), float16_t(C.z))) + spvNClamp(A.z, B.z, C.z)));
    SV_Target.w = float(spvNClamp(double(A.w), double(B.w), double(C.w)) + double(float(spvNClamp(float16_t(A.w), float16_t(B.w), float16_t(C.w))) + spvNClamp(A.w, B.w, C.w)));
}

