51 lines
2.4 KiB
GLSL
51 lines
2.4 KiB
GLSL
// Shared by the runtime-compiled program and the offline reference target.
|
|
layout(std430,binding=64) buffer LuaTasks { uvec4 luaTasks[]; };
|
|
void main() {
|
|
uint id=gl_GlobalInvocationID.x;
|
|
if(id>=32768u)return;
|
|
FProj p=fprojs[id];
|
|
uvec4 task=luaTasks[id];
|
|
// Gather all additive fields into this target invocation. No invocation
|
|
// writes another projectile, so overlapping fields cannot race or lose force.
|
|
if(p.d.w!=0&&(p.d.z&(1<<29))==0&&p.d.x>=0&&p.d.x<512) {
|
|
uint flags=ft[p.d.x*18+11].y;
|
|
if((flags&(3u<<29))==(3u<<29)) {
|
|
uint count=luaTasks[32768].y==uint(pc.frame)?min(luaTasks[32768].x,512u):0u;
|
|
for(uint field=0u;field<count;++field) {
|
|
uvec4 data=luaTasks[32769u+field*2u];
|
|
uvec4 source=luaTasks[32770u+field*2u];
|
|
if((source.z&1u)!=0u&&source.x==id+1u&&source.y==uint(p.d.w))continue;
|
|
FProj candidate=p;
|
|
uvec4 fault=ngp_neighbor_dispatch(data.z,candidate,vec3(uintBitsToFloat(data.xy),0.0));
|
|
if(fault.x==0u)p=candidate;
|
|
else {luaTasks[id]=uvec4(uint(p.d.w),uint(pc.frame),2u,fault.x);}
|
|
}
|
|
if(count!=0u)fprojs[id]=p;
|
|
}
|
|
}
|
|
if(p.d.w!=0 && p.d.x>=0 && p.d.x<512) {
|
|
const uint flags=ft[p.d.x*18+11].y;
|
|
const uint period=(flags>>21)&255u;
|
|
// bit 30 transfers this instance to a CPU query's materialized twin.
|
|
if((flags&(1u<<20))!=0u && (p.d.z&(1<<30))==0 && period!=0u) {
|
|
if((uint(pc.frame)+uint(p.d.w))%period!=0u)return;
|
|
if(p.a.x<float(pc.view_x-128)||p.a.y<float(pc.view_y-128)||p.a.x>float(pc.view_x+pc.gw+128)||p.a.y>float(pc.view_y+pc.gh+128))return;
|
|
if(task.x==uint(p.d.w)&&task.y==uint(pc.frame)&&task.z==2u)return;
|
|
task=uvec4(uint(p.d.w),uint(pc.frame),257u,0u); // program 1, pending
|
|
luaTasks[id]=task;
|
|
}
|
|
}
|
|
if((task.z&255u)!=1u)return;
|
|
uint program=task.z>>8;
|
|
luaTasks[id].z=2u;
|
|
if(task.y!=uint(pc.frame)||task.x!=uint(p.d.w)||p.d.w==0||(p.d.z&(1<<29))!=0){luaTasks[id].w=13u;return;}
|
|
int owner=int(p.e.z)-1;
|
|
bool known=owner>=0&&owner<ctrl.inp.w;
|
|
if(known)known=(ents[owner].st.w&8)==0;
|
|
// The original chunk does nothing when mWhoShot is NULL_ENTITY.
|
|
vec3 transform=known?vec3(ents[owner].a.xy,0.0):vec3(0.0);
|
|
uvec4 fault=ngp_dispatch(program,p,transform,known?float(owner+1):0.0);
|
|
luaTasks[id].w=fault.x;
|
|
fprojs[id]=p;
|
|
}
|