gol_transfert.glsl 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #version 430
  2. // Game of life transfert shader
  3. #define GOL_WIDTH 768
  4. // Game Of Life Update Command
  5. // NOTE: matches the structure defined on main program
  6. struct GolUpdateCmd {
  7. uint x; // x coordinate of the gol command
  8. uint y; // y coordinate of the gol command
  9. uint w; // width of the filled zone
  10. uint enabled; // whether to enable or disable zone
  11. };
  12. // Local compute unit size
  13. layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
  14. // Output game of life grid buffer
  15. layout(std430, binding = 1) buffer golBufferLayout
  16. {
  17. uint golBuffer[]; // golBuffer[x, y] = golBuffer[x + GOL_WIDTH * y]
  18. };
  19. // Command buffer
  20. layout(std430, binding = 3) readonly restrict buffer golUpdateLayout
  21. {
  22. uint count;
  23. GolUpdateCmd commands[];
  24. };
  25. #define isInside(x, y) (((x) >= 0) && ((y) >= 0) && ((x) < GOL_WIDTH) && ((y) < GOL_WIDTH))
  26. #define getBufferIndex(x, y) ((x) + GOL_WIDTH * (y))
  27. void main()
  28. {
  29. uint cmdIndex = gl_GlobalInvocationID.x;
  30. GolUpdateCmd cmd = commands[cmdIndex];
  31. for (uint x = cmd.x; x < (cmd.x + cmd.w); x++)
  32. {
  33. for (uint y = cmd.y; y < (cmd.y + cmd.w); y++)
  34. {
  35. if (isInside(x, y))
  36. {
  37. if (cmd.enabled != 0) atomicOr(golBuffer[getBufferIndex(x, y)], 1);
  38. else atomicAnd(golBuffer[getBufferIndex(x, y)], 0);
  39. }
  40. }
  41. }
  42. }