#ifndef IDIOMS_GLSL
#define IDIOMS_GLSL

#define HALF_MIN 6.103515625e-5  // 2^-14, the same value for 10, 11 and 16-bit: https://www.khronos.org/opengl/wiki/Small_Float_Formats
#define FLT_EPSILON 1.192092896e-07F

#define int2 ivec2
#define int3 ivec3
#define int4 ivec4

#define uint2 uvec2
#define uint3 uvec3
#define uint4 uvec4

#define short  mediump int
#define short2 mediump ivec2
#define short3 mediump ivec3
#define short4 mediump ivec4

#define ushort  mediump uint
#define ushort2 mediump uvec2
#define ushort3 mediump uvec3
#define ushort4 mediump uvec4

#define half  mediump float
#define half2 mediump vec2
#define half3 mediump vec3
#define half4 mediump vec4

#define float2 vec2
#define float3 vec3
#define float4 vec4

#define half2x2 mediump mat2
#define half2x3 mediump mat2x3
#define half2x4 mediump mat2x4
#define half3x2 mediump mat3x2
#define half3x3 mediump mat3
#define half3x4 mediump mat3x4
#define half4x2 mediump mat4x2
#define half4x3 mediump mat4x3
#define half4x4 mediump mat4

#define float2x2 mat2
#define float2x3 mat2x3
#define float2x4 mat2x4
#define float3x2 mat3x2
#define float3x3 mat3
#define float3x4 mat3x4
#define float4x2 mat4x2
#define float4x3 mat4x3
#define float4x4 mat4

#define lerp(a, b, t) mix(a, b, t)

// Note: _sat(NaN) = 0 in HLSL sematic, but GLSL the value is NaN

#define saturate(x) clamp(x, 0.0, 1.0)

#define mul(v, m) (v) * (m)

#define rsqrt(x) inversesqrt(x)

#define rcp(x) (1.0 / (x))

float asfloat(int x) { return intBitsToFloat(x); }
float asfloat(uint x) { return uintBitsToFloat(x); }
int asint(float x) { return floatBitsToInt(x); }
uint asuint(float x) { return floatBitsToUint(x); }

#ifdef _GLSL_FS
void clip(float expr) { if(expr < 0.0) discard; }
#endif

#define select(a, b, c) lerp(c, b, a)

uint f32tof16(float value) { return packHalf2x16(vec2(0.0,value)); }

float f16tof32(uint value) { return unpackHalf2x16(value).x; }

half inl_half(float v) { return v; }
half2 inl_half(float2 v) { return v; }
half3 inl_half(float3 v) { return v; }
half4 inl_half(float4 v) { return v; }

const float kPI_OVER_TWO = 1.5707963267948966;

float2 sincos(float x){ return sin(float2(x, x + kPI_OVER_TWO)); }
half2 sincosfp16(half x) { half2 xy = float2(x, x + kPI_OVER_TWO); return sin(xy); }

#endif /* IDIOMS_GLSL */
