#include <metal_stdlib>
using namespace metal;

struct tint_module_vars_struct {
  device float* prevent_dce;
  depth2d_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 textureSampleCompareLevel_b6e47c(tint_module_vars_struct tint_module_vars) {
  float2 arg_2 = float2(1.0f);
  int arg_3 = 1;
  float arg_4 = 1.0f;
  float2 const v = arg_2;
  int const v_1 = arg_3;
  float const v_2 = arg_4;
  level const v_3 = level(0u);
  float res = tint_module_vars.arg_0.sample_compare(tint_module_vars.arg_1, v, max(v_1, 0), v_2, v_3, int2(1));
  return res;
}

fragment void fragment_main(device float* prevent_dce [[buffer(0)]], depth2d_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) = textureSampleCompareLevel_b6e47c(tint_module_vars);
}

kernel void compute_main(device float* prevent_dce [[buffer(0)]], depth2d_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) = textureSampleCompareLevel_b6e47c(tint_module_vars);
}

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

vertex vertex_main_outputs vertex_main(depth2d_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_4 = vertex_main_inner(tint_module_vars);
  vertex_main_outputs tint_wrapper_result = {};
  tint_wrapper_result.VertexOutput_pos = v_4.pos;
  tint_wrapper_result.VertexOutput_prevent_dce = v_4.prevent_dce;
  return tint_wrapper_result;
}
