#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device uint* prevent_dce;
  texture1d<int, access::sample> arg_0;
};

struct VertexOutput {
  float4 pos;
  uint prevent_dce;
};

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

uint textureNumLevels_f742c0(tint_module_vars_struct tint_module_vars) {
  uint res = tint_module_vars.arg_0.get_num_mip_levels();
  return res;
}

fragment void fragment_main(device uint* prevent_dce [[buffer(0)]], texture1d<int, access::sample> arg_0 [[texture(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0=arg_0};
  (*tint_module_vars.prevent_dce) = textureNumLevels_f742c0(tint_module_vars);
}

kernel void compute_main(device uint* prevent_dce [[buffer(0)]], texture1d<int, access::sample> arg_0 [[texture(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0=arg_0};
  (*tint_module_vars.prevent_dce) = textureNumLevels_f742c0(tint_module_vars);
}

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

vertex vertex_main_outputs vertex_main(texture1d<int, access::sample> arg_0 [[texture(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0};
  VertexOutput const v = vertex_main_inner(tint_module_vars);
  return vertex_main_outputs{.VertexOutput_pos=v.pos, .VertexOutput_prevent_dce=v.prevent_dce};
}
