cs_drawindirect.sc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright 2022 Liam Twigger. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
  4. */
  5. #include "bgfx_compute.sh"
  6. //instance data for all instances (pre culling)
  7. BUFFER_RO(instanceDataIn, vec4, 0);
  8. // Output
  9. BUFFER_WO(indirectBuffer, uvec4, 1);
  10. BUFFER_WO(instanceBufferOut, vec4, 2);
  11. #ifdef INDIRECT_COUNT
  12. BUFFER_WO(indirectCountBuffer, int, 3);
  13. #endif
  14. uniform vec4 u_drawParams;
  15. // Use 64*1*1 local threads
  16. NUM_THREADS(64, 1, 1)
  17. void main()
  18. {
  19. int tId = int(gl_GlobalInvocationID.x);
  20. int numDrawItems = int(u_drawParams.x);
  21. int sideSize = int(u_drawParams.y);
  22. float time = u_drawParams.z;
  23. // Work out the amount of work we're going to do here
  24. int maxToDraw = min(sideSize*sideSize, numDrawItems);
  25. int numToDrawPerThread = maxToDraw/64 + 1;
  26. int idxStart = tId*numToDrawPerThread;
  27. int idxMax = min(maxToDraw, (tId+1)*numToDrawPerThread);
  28. // Prepare draw mtx
  29. for (int k = idxStart; k < idxMax; k++) {
  30. int yy = k / sideSize;
  31. int xx = k % sideSize;
  32. float _ax = time + xx * 0.21f;
  33. float _ay = time + yy * 0.37f;
  34. float sx = sin(_ax);
  35. float cx = cos(_ax);
  36. float sy = sin(_ay);
  37. float cy = cos(_ay);
  38. vec4 a = vec4( cy, 0, sy, 0);
  39. vec4 b = vec4( sx*sy, cx, -sx*cy, 0);
  40. vec4 c = vec4(-cx*sy, sx, cx*cy, 0);
  41. vec4 d = vec4(-15.0f - (sideSize-11)*1.2f + float(xx) * 3.0f, -15.0f - (sideSize-11)*1.4f + float(yy) * 3.0f, max(0.0f, (sideSize-11.0f)*3.0f), 1.0f);
  42. vec4 color;
  43. color.x = sin(time + float(xx) / 11.0f) * 0.5f + 0.5f;
  44. color.y = cos(time + float(yy) / 11.0f) * 0.5f + 0.5f;
  45. color.z = sin(time * 3.0f) * 0.5f + 0.5f;
  46. color.w = 1.0f;
  47. instanceBufferOut[k*5+0] = a;
  48. instanceBufferOut[k*5+1] = b;
  49. instanceBufferOut[k*5+2] = c;
  50. instanceBufferOut[k*5+3] = d;
  51. instanceBufferOut[k*5+4] = color;
  52. }
  53. // Fill indirect buffer
  54. for (int k = idxStart; k < idxMax; k++) {
  55. drawIndexedIndirect(
  56. // Target location params:
  57. indirectBuffer, // target buffer
  58. k, // index in buffer
  59. // Draw call params:
  60. instanceDataIn[k].w, // number of indices for this draw call
  61. 1u, // number of instances for this draw call. You can disable this draw call by setting to zero
  62. instanceDataIn[k].z, // offset in the index buffer
  63. instanceDataIn[k].x, // offset in the vertex buffer. Note that you can use this to "reindex" submeshses - all indicies in this draw will be decremented by this amount
  64. k // offset in the instance buffer. If you are drawing more than 1 instance per call see gpudrivenrendering for how to handle
  65. );
  66. }
  67. #ifdef INDIRECT_COUNT
  68. if (tId == 0)
  69. {
  70. // If BGFX_CAPS_DRAW_INDIRECT_COUNT is supported, you can limit the
  71. // number of draw calls dynamically without a CPU round trip
  72. indirectCountBuffer[0] = maxToDraw;
  73. }
  74. #endif
  75. }