// language: metal2.4
#include <metal_stdlib>
#include <simd/simd.h>

using metal::uint;
struct _RayQuery {
    metal::raytracing::intersector<metal::raytracing::instancing, metal::raytracing::triangle_data, metal::raytracing::world_space_data> intersector;
    metal::raytracing::intersector<metal::raytracing::instancing, metal::raytracing::triangle_data, metal::raytracing::world_space_data>::result_type intersection;
    bool ready = false;
};
constexpr metal::uint _map_intersection_type(const metal::raytracing::intersection_type ty) {
    return ty==metal::raytracing::intersection_type::triangle ? 1 : 
        ty==metal::raytracing::intersection_type::bounding_box ? 4 : 0;
}

struct RayDesc {
    uint flags;
    uint cull_mask;
    float tmin;
    float tmax;
    metal::float3 origin;
    metal::float3 dir;
};
constant float o = 2.0;

kernel void main_(
  metal::raytracing::instance_acceleration_structure acc_struct [[user(fake0)]]
) {
    _RayQuery rq = {};
    RayDesc desc = RayDesc {4u, 255u, 34.0, 38.0, metal::float3(46.0), metal::float3(58.0, 62.0, 74.0)};
    rq.intersector.assume_geometry_type(metal::raytracing::geometry_type::triangle);
    rq.intersector.set_opacity_cull_mode((desc.flags & 64) != 0 ? metal::raytracing::opacity_cull_mode::opaque : (desc.flags & 128) != 0 ? metal::raytracing::opacity_cull_mode::non_opaque : metal::raytracing::opacity_cull_mode::none);
    rq.intersector.force_opacity((desc.flags & 1) != 0 ? metal::raytracing::forced_opacity::opaque : (desc.flags & 2) != 0 ? metal::raytracing::forced_opacity::non_opaque : metal::raytracing::forced_opacity::none);
    rq.intersector.accept_any_intersection((desc.flags & 4) != 0);
    rq.intersection = rq.intersector.intersect(metal::raytracing::ray(desc.origin, desc.dir, desc.tmin, desc.tmax), acc_struct, desc.cull_mask);    rq.ready = true;
    uint2 loop_bound = uint2(0u);
    while(true) {
        if (metal::all(loop_bound == uint2(4294967295u))) { break; }
        loop_bound += uint2(loop_bound.y == 4294967295u, 1u);
        bool _e31 = rq.ready;
        if (_e31) {
        } else {
            break;
        }
    }
    return;
}
