| #pragma clang diagnostic ignored "-Wmissing-prototypes" |
| |
| #include <metal_stdlib> |
| #include <simd/simd.h> |
| |
| using namespace metal; |
| |
| struct Bic |
| { |
| uint a; |
| uint b; |
| }; |
| |
| struct Bic_1 |
| { |
| uint a; |
| uint b; |
| }; |
| |
| struct BicBuf |
| { |
| Bic_1 bicbuf[1]; |
| }; |
| |
| struct StackBuf |
| { |
| float4 stack[1]; |
| }; |
| |
| struct Node |
| { |
| uint node_type; |
| uint pad1; |
| uint pad2; |
| uint pad3; |
| float4 bbox; |
| }; |
| |
| struct Node_1 |
| { |
| uint node_type; |
| uint pad1; |
| uint pad2; |
| uint pad3; |
| float4 bbox; |
| }; |
| |
| struct InBuf |
| { |
| Node_1 inbuf[1]; |
| }; |
| |
| struct OutBuf |
| { |
| float4 outbuf[1]; |
| }; |
| |
| constant uint3 gl_WorkGroupSize [[maybe_unused]] = uint3(512u, 1u, 1u); |
| |
| static inline __attribute__((always_inline)) |
| Bic bic_combine(thread const Bic& x, thread const Bic& y) |
| { |
| uint m = min(x.b, y.a); |
| return Bic{ (x.a + y.a) - m, (x.b + y.b) - m }; |
| } |
| |
| static inline __attribute__((always_inline)) |
| float4 bbox_intersect(thread const float4& a, thread const float4& b) |
| { |
| return float4(fast::max(a.xy, b.xy), fast::min(a.zw, b.zw)); |
| } |
| |
| kernel void main0(const device InBuf& _285 [[buffer(0)]], const device BicBuf& _89 [[buffer(1)]], const device StackBuf& _167 [[buffer(2)]], device OutBuf& _520 [[buffer(3)]], uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]], uint3 gl_WorkGroupID [[threadgroup_position_in_grid]], uint3 gl_GlobalInvocationID [[thread_position_in_grid]]) |
| { |
| threadgroup Bic sh_bic[1022]; |
| threadgroup float4 sh_bbox[512]; |
| threadgroup float4 sh_stack[512]; |
| threadgroup uint sh_link[512]; |
| uint th = gl_LocalInvocationID.x; |
| Bic bic = Bic{ 0u, 0u }; |
| if (th < gl_WorkGroupID.x) |
| { |
| bic.a = _89.bicbuf[th].a; |
| bic.b = _89.bicbuf[th].b; |
| } |
| sh_bic[th] = bic; |
| for (uint i = 0u; i < 9u; i++) |
| { |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| uint other_ix = th + (1u << i); |
| if (other_ix < 512u) |
| { |
| Bic param = bic; |
| Bic param_1 = sh_bic[other_ix]; |
| bic = bic_combine(param, param_1); |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| sh_bic[th] = bic; |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| uint size = sh_bic[0].b; |
| uint bic_next_b = 0u; |
| if ((th + 1u) < 512u) |
| { |
| bic_next_b = sh_bic[th + 1u].b; |
| } |
| float4 bbox = float4(-1000000000.0, -1000000000.0, 1000000000.0, 1000000000.0); |
| if (bic.b > bic_next_b) |
| { |
| bbox = _167.stack[(((th * 512u) + bic.b) - bic_next_b) - 1u]; |
| } |
| for (uint i_1 = 0u; i_1 < 9u; i_1++) |
| { |
| sh_bbox[th] = bbox; |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| if (th >= (1u << i_1)) |
| { |
| float4 param_2 = sh_bbox[th - (1u << i_1)]; |
| float4 param_3 = bbox; |
| bbox = bbox_intersect(param_2, param_3); |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| } |
| sh_bbox[th] = bbox; |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| uint sp = 511u - th; |
| uint ix = 0u; |
| for (uint i_2 = 0u; i_2 < 9u; i_2++) |
| { |
| uint probe = ix + (256u >> i_2); |
| if (sp < sh_bic[probe].b) |
| { |
| ix = probe; |
| } |
| } |
| uint b = sh_bic[ix].b; |
| if (sp < b) |
| { |
| bbox = _167.stack[(((ix * 512u) + b) - sp) - 1u]; |
| if (ix > 0u) |
| { |
| float4 param_4 = sh_bbox[ix - 1u]; |
| float4 param_5 = bbox; |
| bbox = bbox_intersect(param_4, param_5); |
| } |
| sh_stack[th] = bbox; |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| Node inp; |
| inp.node_type = _285.inbuf[gl_GlobalInvocationID.x].node_type; |
| inp.pad1 = _285.inbuf[gl_GlobalInvocationID.x].pad1; |
| inp.pad2 = _285.inbuf[gl_GlobalInvocationID.x].pad2; |
| inp.pad3 = _285.inbuf[gl_GlobalInvocationID.x].pad3; |
| inp.bbox = _285.inbuf[gl_GlobalInvocationID.x].bbox; |
| uint node_type = inp.node_type; |
| bic = Bic{ uint(node_type == 1u), uint(node_type == 0u) }; |
| sh_bic[th] = bic; |
| uint inbase = 0u; |
| for (uint i_3 = 0u; i_3 < 8u; i_3++) |
| { |
| uint outbase = 1024u - (1u << (9u - i_3)); |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| if (th < (1u << (8u - i_3))) |
| { |
| Bic param_6 = sh_bic[inbase + (th * 2u)]; |
| Bic param_7 = sh_bic[(inbase + (th * 2u)) + 1u]; |
| sh_bic[outbase + th] = bic_combine(param_6, param_7); |
| } |
| inbase = outbase; |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| ix = th; |
| bic = Bic{ 0u, 0u }; |
| uint j = 0u; |
| while (j < 9u) |
| { |
| uint base = 1024u - (2u << (9u - j)); |
| if (((ix >> j) & 1u) != 0u) |
| { |
| Bic param_8 = sh_bic[(base + (ix >> j)) - 1u]; |
| Bic param_9 = bic; |
| Bic test = bic_combine(param_8, param_9); |
| if (test.b > 0u) |
| { |
| break; |
| } |
| bic = test; |
| ix -= (1u << j); |
| } |
| j++; |
| } |
| if (ix > 0u) |
| { |
| while (j > 0u) |
| { |
| j--; |
| uint base_1 = 1024u - (2u << (9u - j)); |
| Bic param_10 = sh_bic[(base_1 + (ix >> j)) - 1u]; |
| Bic param_11 = bic; |
| Bic test_1 = bic_combine(param_10, param_11); |
| if (test_1.b == 0u) |
| { |
| bic = test_1; |
| ix -= (1u << j); |
| } |
| } |
| } |
| uint _455; |
| if (ix > 0u) |
| { |
| _455 = ix - 1u; |
| } |
| else |
| { |
| _455 = 4294967295u - bic.a; |
| } |
| uint link = _455; |
| bbox = inp.bbox; |
| for (uint i_4 = 0u; i_4 < 9u; i_4++) |
| { |
| sh_link[th] = link; |
| sh_bbox[th] = bbox; |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| if (int(link) >= 0) |
| { |
| float4 param_12 = sh_bbox[link]; |
| float4 param_13 = bbox; |
| bbox = bbox_intersect(param_12, param_13); |
| link = sh_link[link]; |
| } |
| threadgroup_barrier(mem_flags::mem_threadgroup); |
| } |
| if (int(link + size) >= 0) |
| { |
| float4 param_14 = sh_stack[512u + link]; |
| float4 param_15 = bbox; |
| bbox = bbox_intersect(param_14, param_15); |
| } |
| _520.outbuf[gl_GlobalInvocationID.x] = bbox; |
| } |
| |