#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 {
  texture2d<float, access::sample> arg_0_plane0;
  texture2d<float, access::sample> arg_0_plane1;
  const constant tint_ExternalTextureParams_packed_vec3* arg_0_params;
};

struct vertex_main_outputs {
  float4 tint_symbol_1 [[position]];
};

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_TextureLoadExternal(texture2d<float, access::sample> plane_0, texture2d<float, access::sample> plane_1, tint_ExternalTextureParams params, uint2 coords) {
  float2 const v_5 = rint((params.loadTransform * float3(float2(min(coords, params.visibleSize)), 1.0f)));
  uint2 const v_6 = uint2(v_5);
  float3 v_7 = 0.0f;
  float v_8 = 0.0f;
  if ((params.numPlanes == 1u)) {
    float4 const v_9 = plane_0.read(v_6, 0u);
    v_7 = v_9.xyz;
    v_8 = v_9[3u];
  } else {
    float const v_10 = plane_0.read(v_6, 0u)[0u];
    v_7 = (float4(v_10, plane_1.read(uint2((v_5 * params.plane1CoordFactor)), 0u).xy, 1.0f) * params.yuvToRgbConversionMatrix);
    v_8 = 1.0f;
  }
  float3 const v_11 = v_7;
  float3 v_12 = 0.0f;
  if ((params.doYuvToRgbConversionOnly == 0u)) {
    v_12 = tint_GammaCorrection((params.gamutConversionMatrix * tint_GammaCorrection(v_11, params.gammaDecodeParams)), params.gammaEncodeParams);
  } else {
    v_12 = v_11;
  }
  return float4(v_12, v_8);
}

float4 textureLoad2d(texture2d<float, access::sample> tint_symbol_plane0, texture2d<float, access::sample> tint_symbol_plane1, tint_ExternalTextureParams tint_symbol_params, int2 coords) {
  return tint_TextureLoadExternal(tint_symbol_plane0, tint_symbol_plane1, tint_symbol_params, uint2(coords));
}

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

void doTextureLoad(tint_module_vars_struct tint_module_vars) {
  float4 res = textureLoad2d(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, tint_load_struct_packed_vec3(tint_module_vars.arg_0_params), int2(0));
}

float4 vertex_main_inner(tint_module_vars_struct tint_module_vars) {
  doTextureLoad(tint_module_vars);
  return float4(0.0f);
}

fragment void fragment_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)]]) {
  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};
  doTextureLoad(tint_module_vars);
}

kernel void compute_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)]]) {
  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};
  doTextureLoad(tint_module_vars);
}

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)]]) {
  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};
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.tint_symbol_1 = vertex_main_inner(tint_module_vars);
  return tint_wrapper_result;
}
