123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- #version 430
- // Game of life transfert shader
- #define GOL_WIDTH 768
- // Game Of Life Update Command
- // NOTE: matches the structure defined on main program
- struct GolUpdateCmd {
- uint x; // x coordinate of the gol command
- uint y; // y coordinate of the gol command
- uint w; // width of the filled zone
- uint enabled; // whether to enable or disable zone
- };
- // Local compute unit size
- layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
- // Output game of life grid buffer
- layout(std430, binding = 1) buffer golBufferLayout
- {
- uint golBuffer[]; // golBuffer[x, y] = golBuffer[x + GOL_WIDTH * y]
- };
- // Command buffer
- layout(std430, binding = 3) readonly restrict buffer golUpdateLayout
- {
- uint count;
- GolUpdateCmd commands[];
- };
- #define isInside(x, y) (((x) >= 0) && ((y) >= 0) && ((x) < GOL_WIDTH) && ((y) < GOL_WIDTH))
- #define getBufferIndex(x, y) ((x) + GOL_WIDTH * (y))
- void main()
- {
- uint cmdIndex = gl_GlobalInvocationID.x;
- GolUpdateCmd cmd = commands[cmdIndex];
- for (uint x = cmd.x; x < (cmd.x + cmd.w); x++)
- {
- for (uint y = cmd.y; y < (cmd.y + cmd.w); y++)
- {
- if (isInside(x, y))
- {
- if (cmd.enabled != 0) atomicOr(golBuffer[getBufferIndex(x, y)], 1);
- else atomicAnd(golBuffer[getBufferIndex(x, y)], 0);
- }
- }
- }
- }
|