28 lines
1.2 KiB
Plaintext
28 lines
1.2 KiB
Plaintext
#version 450
|
|
#extension GL_GOOGLE_include_directive : require
|
|
layout(local_size_x = 8, local_size_y = 8) in;
|
|
#include "common.glsl"
|
|
|
|
// Performs the moves that won claim arbitration. A mover wins only if it holds the highest
|
|
// priority on both its source and its target cell, so the winners' cell pairs are disjoint and
|
|
// no atomics or ordering are needed here. The displaced occupant takes the mover's old slot
|
|
// (the original's swap-based move primitive, FUN_0070cc00).
|
|
void main() {
|
|
ivec2 p = ivec2(gl_GlobalInvocationID.xy);
|
|
if (p.x >= pc.gw || p.y >= pc.gh) return;
|
|
uint i = uint(p.y * pc.gw + p.x);
|
|
uvec4 it = intent[i];
|
|
if (it.x == NONE) return;
|
|
uint t = it.x & 0x7FFFFFFFu;
|
|
if (claims[i] != it.y || claims[t] != it.y) return; // lost arbitration, retry next pass
|
|
|
|
uint cs = cells[i], ct = cells[t];
|
|
vec2 et = ext[t];
|
|
if ((it.x >> 31) != 0u) cs ^= DIR_BIT; // gas bounced: flip horizontal direction
|
|
cells[t] = cs;
|
|
ext[t] = vec2(uintBitsToFloat(it.z), uintBitsToFloat(it.w));
|
|
cells[i] = ct;
|
|
ext[i] = et;
|
|
const uint bt = birth[t]; birth[t] = birth[i]; birth[i] = bt; // the age moves with the cell
|
|
}
|