#include <metal_stdlib>

using namespace metal;
uint4 textureGather_ce5578(texture2d_array<uint, access::sample> tint_symbol_1, sampler tint_symbol_2) {
  float2 arg_3 = float2(1.0f);
  uint arg_4 = 1u;
  uint4 res = tint_symbol_1.gather(tint_symbol_2, arg_3, arg_4, int2(1), component::y);
  return res;
}

fragment void fragment_main(device uint4* tint_symbol_3 [[buffer(0)]], texture2d_array<uint, access::sample> tint_symbol_4 [[texture(0)]], sampler tint_symbol_5 [[sampler(0)]]) {
  *(tint_symbol_3) = textureGather_ce5578(tint_symbol_4, tint_symbol_5);
  return;
}

kernel void compute_main(device uint4* tint_symbol_6 [[buffer(0)]], texture2d_array<uint, access::sample> tint_symbol_7 [[texture(0)]], sampler tint_symbol_8 [[sampler(0)]]) {
  *(tint_symbol_6) = textureGather_ce5578(tint_symbol_7, tint_symbol_8);
  return;
}

struct VertexOutput {
  float4 pos;
  uint4 prevent_dce;
};

struct tint_symbol {
  uint4 prevent_dce [[user(locn0)]] [[flat]];
  float4 pos [[position]];
};

VertexOutput vertex_main_inner(texture2d_array<uint, access::sample> tint_symbol_9, sampler tint_symbol_10) {
  VertexOutput out = {};
  out.pos = float4(0.0f);
  out.prevent_dce = textureGather_ce5578(tint_symbol_9, tint_symbol_10);
  return out;
}

vertex tint_symbol vertex_main(texture2d_array<uint, access::sample> tint_symbol_11 [[texture(0)]], sampler tint_symbol_12 [[sampler(0)]]) {
  VertexOutput const inner_result = vertex_main_inner(tint_symbol_11, tint_symbol_12);
  tint_symbol wrapper_result = {};
  wrapper_result.pos = inner_result.pos;
  wrapper_result.prevent_dce = inner_result.prevent_dce;
  return wrapper_result;
}

