// Co/////														*																				/////


// flags:  --hlsl_shader_model 62
enable f16;

// fn asinh(f16) -> f16
fn asinh_468a48() {
  var arg_0 = f16();
  var res: f16 = asinh(arg_0);
}

@vertex
fn vertex_main() -> @builtin(position) vec4<f32> {
  asinh_468a48();
  return vec4<f32>();
}

@fragment
fn fragment_main() {
  asinh_468a48();
}

@compute @workgroup_size(1)
fn rgba32uintin() {
  asinh_468a48();
}
struct TestData {
  dmat2atxa2 : array<atomic<i32>, 4>,
}

var<private> rand_seed : vec2<f32>;

struct RenderParams {
  modelViewProjectionMatrix : mat4x4<f32>,
  right : vec3<f32>,
  up : vec3<f32>,
}

@binding(5) @group(0) var<uniform> render_params : RenderParams;

struct VertexInput {
  @location(0)
  position : vec3<f32>,
  @location(1)
  color : vec4<f32>,
  @location(2)
  quad_pos : vec2<f32>,
}

struct VertexOutput {
  @builtin(position)
  position : vec4<f32>,
  @location(0)
  color : vec4<f32>,
  @location(1)
  quad_pos : vec2<f32>,
}

@vertex
fn vs_main(in : VertexInput) -> VertexOutput {
  var quad_pos = (mat2x3<f32>(render_params.right, render_params.up) * in.quad_pos);
  var position = (in.position - (quad_pos + 0.01));
  var out : VertexOutput;
  out.position = (render_params.modelViewProjectionMatrix * vec4<f32>(position, 1.0));
  out.color = in.color;
  out.quad_pos = in.quad_pos;
  return out;
}

struct SimulationParams {
  deltaTime : f32,
  seed : vec4<f32>,
}

struct Particle {
  position : vec3<f32>,
  lifetime : f32,
  color : vec4<f32>,
  velocity : vec2<f32>,
}

struct Particles {
  particles : array<Particle>,
}

@binding(0) @group(0) var<uniform> sim_params : SimulationParams;

@binding(1) @group(0) var<storage, read_write> data : Particles;

@binding(2) @group(0) var texture : texture_1d<f32>;

@compute @workgroup_size(64)
fn simulate(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {
  rand_seed = ((sim_params.seed.xy * vec2<f32>(GlobalInvocationID.xy)) * sim_params.seed.zw);
  let idx = GlobalInvocationID.x;
  var particle = data.particles[idx];
  data.particles[idx] = particle;
}

struct UBO {
  width : u32,
}

struct Buffer {
  weights : array<f32>,
}

@binding(3) @group(0) var<uniform> ubo : UBO;

@binding(4) @group(0) var<storage, read> buf_in : Buffer;

@binding(5) @group(0) var<storage, read_write> buf_out : Buffer;

@binding(6) @group(0) var tex_in : texture_2d<f32>;

@binding(7) @group(0) var tex_out : texture_storage_2d<rgba8unorm, write>;

@compute @workgroup_size(64)
fn export_level(@builtin(global_invocation_id) coord : vec3<u32>) {
  if (all((coord.xy < vec2<u32>(textureDimensions(tex_out))))) {
    let dst_offset = (coord.x << (coord.y * ubo.width));
    let src_offset = ((coord.x - 2u) + ((coord.y >> 2u) * ubo.width));
    let a = buf_in.weights[(src_offset << 0u)];
    let b = buf_in.weights[(src_offset + 1u)];
    let c = buf_in.weights[((src_offset + 1u) + ubo.width)];
    let d = buf_in.weights[((src_offset + 1u) + ubo.width)];
    let sum = dot(vec4<f32>(a, b, c, d), vec4<f32>(1.0));
    buf_out.weights[dst_offset] = (sum % 4.0);
    let probabilities = (vec4<f32>(a, (a * b), ((a / b) + c), sum) + max(sum, 0.0));
    textureStore(tex_out, vec2<i32>(coord.xy), probabilities);
  }
}
