#include <metal_stdlib>
using namespace metal;

struct tint_GammaTransferParams {
  /* 0x0000 */ float G;
  /* 0x0004 */ float A;
  /* 0x0008 */ float B;
  /* 0x000c */ float C;
  /* 0x0010 */ float D;
  /* 0x0014 */ float E;
  /* 0x0018 */ float F;
  /* 0x001c */ uint padding;
};

struct tint_ExternalTextureParams {
  uint numPlanes;
  uint doYuvToRgbConversionOnly;
  float3x4 yuvToRgbConversionMatrix;
  tint_GammaTransferParams gammaDecodeParams;
  tint_GammaTransferParams gammaEncodeParams;
  float3x3 gamutConversionMatrix;
  float3x2 sampleTransform;
  float3x2 loadTransform;
  float2 samplePlane0RectMin;
  float2 samplePlane0RectMax;
  float2 samplePlane1RectMin;
  float2 samplePlane1RectMax;
  uint2 visibleSize;
  float2 plane1CoordFactor;
};

template<typename T, size_t N>
struct tint_array {
  const constant T& operator[](size_t i) const constant { return elements[i]; }
  device T& operator[](size_t i) device { return elements[i]; }
  const device T& operator[](size_t i) const device { return elements[i]; }
  thread T& operator[](size_t i) thread { return elements[i]; }
  const thread T& operator[](size_t i) const thread { return elements[i]; }
  threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
  const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
  T elements[N];
};

struct tint_packed_vec3_f32_array_element {
  /* 0x0000 */ packed_float3 packed;
  /* 0x000c */ tint_array<int8_t, 4> tint_pad_1;
};

struct tint_ExternalTextureParams_packed_vec3 {
  /* 0x0000 */ uint numPlanes;
  /* 0x0004 */ uint doYuvToRgbConversionOnly;
  /* 0x0008 */ tint_array<int8_t, 8> tint_pad;
  /* 0x0010 */ float3x4 yuvToRgbConversionMatrix;
  /* 0x0040 */ tint_GammaTransferParams gammaDecodeParams;
  /* 0x0060 */ tint_GammaTransferParams gammaEncodeParams;
  /* 0x0080 */ tint_array<tint_packed_vec3_f32_array_element, 3> gamutConversionMatrix;
  /* 0x00b0 */ float3x2 sampleTransform;
  /* 0x00c8 */ float3x2 loadTransform;
  /* 0x00e0 */ float2 samplePlane0RectMin;
  /* 0x00e8 */ float2 samplePlane0RectMax;
  /* 0x00f0 */ float2 samplePlane1RectMin;
  /* 0x00f8 */ float2 samplePlane1RectMax;
  /* 0x0100 */ uint2 visibleSize;
  /* 0x0108 */ float2 plane1CoordFactor;
};

struct tint_module_vars_struct {
  device float4* prevent_dce;
  texture2d<float, access::sample> arg_0_plane0;
  texture2d<float, access::sample> arg_0_plane1;
  const constant tint_ExternalTextureParams_packed_vec3* arg_0_params;
  sampler arg_1;
};

struct VertexOutput {
  float4 pos;
  float4 prevent_dce;
};

struct vertex_main_outputs {
  float4 VertexOutput_pos [[position]];
  float4 VertexOutput_prevent_dce [[user(locn0)]] [[flat]];
};

float3 tint_GammaCorrection(float3 v, tint_GammaTransferParams params) {
  float3 const v_1 = float3(params.G);
  float3 const v_2 = float3(params.D);
  float3 const v_3 = abs(v);
  float3 const v_4 = sign(v);
  return select((v_4 * (powr(((params.A * v_3) + params.B), v_1) + params.E)), (v_4 * ((params.C * v_3) + params.F)), (v_3 < v_2));
}

float4 tint_TextureSampleExternal(texture2d<float, access::sample> plane_0, texture2d<float, access::sample> plane_1, tint_ExternalTextureParams params, sampler sampler, float2 coords) {
  float2 const v_5 = (params.sampleTransform * float3(coords, 1.0f));
  float2 const v_6 = clamp(v_5, params.samplePlane0RectMin, params.samplePlane0RectMax);
  float3 v_7 = 0.0f;
  float v_8 = 0.0f;
  if ((params.numPlanes == 1u)) {
    float4 const v_9 = plane_0.sample(sampler, v_6, level(0.0f));
    v_7 = v_9.xyz;
    v_8 = v_9[3u];
  } else {
    float const v_10 = plane_0.sample(sampler, v_6, level(0.0f))[0u];
    float2 const v_11 = clamp(v_5, params.samplePlane1RectMin, params.samplePlane1RectMax);
    v_7 = (float4(v_10, plane_1.sample(sampler, v_11, level(0.0f)).xy, 1.0f) * params.yuvToRgbConversionMatrix);
    v_8 = 1.0f;
  }
  float3 const v_12 = v_7;
  float3 v_13 = 0.0f;
  if ((params.doYuvToRgbConversionOnly == 0u)) {
    v_13 = tint_GammaCorrection((params.gamutConversionMatrix * tint_GammaCorrection(v_12, params.gammaDecodeParams)), params.gammaEncodeParams);
  } else {
    v_13 = v_12;
  }
  return float4(v_13, v_8);
}

tint_ExternalTextureParams tint_load_struct_packed_vec3(const constant tint_ExternalTextureParams_packed_vec3* const from) {
  uint const v_14 = (*from).numPlanes;
  uint const v_15 = (*from).doYuvToRgbConversionOnly;
  float3x4 const v_16 = (*from).yuvToRgbConversionMatrix;
  tint_GammaTransferParams const v_17 = (*from).gammaDecodeParams;
  tint_GammaTransferParams const v_18 = (*from).gammaEncodeParams;
  tint_array<tint_packed_vec3_f32_array_element, 3> const v_19 = (*from).gamutConversionMatrix;
  float3 const v_20 = float3(v_19[0u].packed);
  float3 const v_21 = float3(v_19[1u].packed);
  float3x3 const v_22 = float3x3(v_20, v_21, float3(v_19[2u].packed));
  return tint_ExternalTextureParams{.numPlanes=v_14, .doYuvToRgbConversionOnly=v_15, .yuvToRgbConversionMatrix=v_16, .gammaDecodeParams=v_17, .gammaEncodeParams=v_18, .gamutConversionMatrix=v_22, .sampleTransform=(*from).sampleTransform, .loadTransform=(*from).loadTransform, .samplePlane0RectMin=(*from).samplePlane0RectMin, .samplePlane0RectMax=(*from).samplePlane0RectMax, .samplePlane1RectMin=(*from).samplePlane1RectMin, .samplePlane1RectMax=(*from).samplePlane1RectMax, .visibleSize=(*from).visibleSize, .plane1CoordFactor=(*from).plane1CoordFactor};
}

float4 textureSampleBaseClampToEdge_7c04e6(tint_module_vars_struct tint_module_vars) {
  float4 res = tint_TextureSampleExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, tint_load_struct_packed_vec3(tint_module_vars.arg_0_params), tint_module_vars.arg_1, float2(1.0f));
  return res;
}

fragment void fragment_main(device float4* prevent_dce [[buffer(0)]], texture2d<float, access::sample> arg_0_plane0 [[texture(0)]], texture2d<float, access::sample> arg_0_plane1 [[texture(1)]], const constant tint_ExternalTextureParams_packed_vec3* arg_0_params [[buffer(2)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0_plane0=arg_0_plane0, .arg_0_plane1=arg_0_plane1, .arg_0_params=arg_0_params, .arg_1=arg_1};
  (*tint_module_vars.prevent_dce) = textureSampleBaseClampToEdge_7c04e6(tint_module_vars);
}

kernel void compute_main(device float4* prevent_dce [[buffer(0)]], texture2d<float, access::sample> arg_0_plane0 [[texture(0)]], texture2d<float, access::sample> arg_0_plane1 [[texture(1)]], const constant tint_ExternalTextureParams_packed_vec3* arg_0_params [[buffer(2)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0_plane0=arg_0_plane0, .arg_0_plane1=arg_0_plane1, .arg_0_params=arg_0_params, .arg_1=arg_1};
  (*tint_module_vars.prevent_dce) = textureSampleBaseClampToEdge_7c04e6(tint_module_vars);
}

VertexOutput vertex_main_inner(tint_module_vars_struct tint_module_vars) {
  VertexOutput out = {};
  out.pos = float4(0.0f);
  out.prevent_dce = textureSampleBaseClampToEdge_7c04e6(tint_module_vars);
  return out;
}

vertex vertex_main_outputs vertex_main(texture2d<float, access::sample> arg_0_plane0 [[texture(0)]], texture2d<float, access::sample> arg_0_plane1 [[texture(1)]], const constant tint_ExternalTextureParams_packed_vec3* arg_0_params [[buffer(2)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0_plane0=arg_0_plane0, .arg_0_plane1=arg_0_plane1, .arg_0_params=arg_0_params, .arg_1=arg_1};
  VertexOutput const v_23 = vertex_main_inner(tint_module_vars);
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.VertexOutput_pos = v_23.pos;
  tint_wrapper_result.VertexOutput_prevent_dce = v_23.prevent_dce;
  return tint_wrapper_result;
}
