#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);
  return select((sign(v) * (powr(((params.A * abs(v)) + params.B), v_1) + params.E)), (sign(v) * ((params.C * abs(v)) + params.F)), (abs(v) < float3(params.D)));
}

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

tint_ExternalTextureParams tint_load_struct_packed_vec3(const constant tint_ExternalTextureParams_packed_vec3* const from) {
  uint const v_10 = (*from).numPlanes;
  uint const v_11 = (*from).doYuvToRgbConversionOnly;
  float3x4 const v_12 = (*from).yuvToRgbConversionMatrix;
  tint_GammaTransferParams const v_13 = (*from).gammaDecodeParams;
  tint_GammaTransferParams const v_14 = (*from).gammaEncodeParams;
  tint_array<tint_packed_vec3_f32_array_element, 3> const v_15 = (*from).gamutConversionMatrix;
  float3 const v_16 = float3(v_15[0u].packed);
  float3 const v_17 = float3(v_15[1u].packed);
  float3x3 const v_18 = float3x3(v_16, v_17, float3(v_15[2u].packed));
  return tint_ExternalTextureParams{.numPlanes=v_10, .doYuvToRgbConversionOnly=v_11, .yuvToRgbConversionMatrix=v_12, .gammaDecodeParams=v_13, .gammaEncodeParams=v_14, .gamutConversionMatrix=v_18, .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_8acf41(tint_module_vars_struct tint_module_vars) {
  int2 arg_1 = int2(1);
  tint_ExternalTextureParams const v_19 = 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_19, uint2(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_8acf41(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_8acf41(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_8acf41(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_20 = vertex_main_inner(tint_module_vars);
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.VertexOutput_pos = v_20.pos;
  tint_wrapper_result.VertexOutput_prevent_dce = v_20.prevent_dce;
  return tint_wrapper_result;
}
