#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device float* prevent_dce;
  depthcube_array<float, access::sample> arg_0;
  sampler arg_1;
};

struct VertexOutput {
  float4 pos;
  float prevent_dce;
};

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

float textureSampleLevel_a12142(tint_module_vars_struct tint_module_vars) {
  float3 arg_2 = float3(1.0f);
  int arg_3 = 1;
  uint arg_4 = 1u;
  float3 const v = arg_2;
  int const v_1 = arg_3;
  float res = tint_module_vars.arg_0.sample(tint_module_vars.arg_1, v, v_1, level(arg_4));
  return res;
}

fragment void fragment_main(device float* prevent_dce [[buffer(0)]], depthcube_array<float, access::sample> arg_0 [[texture(0)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0=arg_0, .arg_1=arg_1};
  (*tint_module_vars.prevent_dce) = textureSampleLevel_a12142(tint_module_vars);
}

kernel void compute_main(device float* prevent_dce [[buffer(0)]], depthcube_array<float, access::sample> arg_0 [[texture(0)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.prevent_dce=prevent_dce, .arg_0=arg_0, .arg_1=arg_1};
  (*tint_module_vars.prevent_dce) = textureSampleLevel_a12142(tint_module_vars);
}

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

vertex vertex_main_outputs vertex_main(depthcube_array<float, access::sample> arg_0 [[texture(0)]], sampler arg_1 [[sampler(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.arg_0=arg_0, .arg_1=arg_1};
  VertexOutput const v_2 = vertex_main_inner(tint_module_vars);
  return vertex_main_outputs{.VertexOutput_pos=v_2.pos, .VertexOutput_prevent_dce=v_2.prevent_dce};
}
