#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;
};

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_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);
}

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};
}

float4 textureLoad_1bfdfb(tint_module_vars_struct tint_module_vars) {
  uint2 arg_1 = uint2(1u);
  tint_ExternalTextureParams const v_22 = tint_load_struct_packed_vec3(tint_module_vars.arg_0_params);
  float4 res = tint_TextureLoadExternal(tint_module_vars.arg_0_plane0, tint_module_vars.arg_0_plane1, v_22, arg_1);
  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)]]) {
  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};
  (*tint_module_vars.prevent_dce) = textureLoad_1bfdfb(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)]]) {
  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};
  (*tint_module_vars.prevent_dce) = textureLoad_1bfdfb(tint_module_vars);
}

VertexOutput vertex_main_inner(tint_module_vars_struct tint_module_vars) {
  VertexOutput out = {};
  out.pos = float4(0.0f);
  out.prevent_dce = textureLoad_1bfdfb(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)]]) {
  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};
  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;
}
