#include <metal_stdlib>
using namespace metal;

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

struct VertexOutput {
  float4 pos;
  uint3 prevent_dce;
};

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

uint3 textureDimensions_e5a203(tint_module_vars_struct tint_module_vars) {
  int arg_1 = 1;
  uint const v = uint(arg_1);
  uint const v_1 = tint_module_vars.arg_0.get_width(v);
  uint const v_2 = tint_module_vars.arg_0.get_height(v);
  uint3 res = uint3(v_1, v_2, tint_module_vars.arg_0.get_depth(v));
  return res;
}

fragment void fragment_main(device uint3* prevent_dce [[buffer(0)]], texture3d<uint, 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) = textureDimensions_e5a203(tint_module_vars);
}

kernel void compute_main(device uint3* prevent_dce [[buffer(0)]], texture3d<uint, 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) = textureDimensions_e5a203(tint_module_vars);
}

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

vertex vertex_main_outputs vertex_main(texture3d<uint, 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_3 = vertex_main_inner(tint_module_vars);
  return vertex_main_outputs{.VertexOutput_pos=v_3.pos, .VertexOutput_prevent_dce=v_3.prevent_dce};
}
