Açıklama Yok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Scan.cs 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. namespace UnityEngine.Rendering.RadeonRays
  2. {
  3. internal class Scan
  4. {
  5. private ComputeShader shaderScan;
  6. private int kernelScan;
  7. private ComputeShader shaderReduce;
  8. private int kernelReduce;
  9. const uint kKeysPerThread = 4u;
  10. const uint kGroupSize = 256u;
  11. const uint kKeysPerGroup = kKeysPerThread * kGroupSize;
  12. public Scan(RadeonRaysShaders shaders)
  13. {
  14. shaderScan = shaders.blockScan;
  15. kernelScan = shaderScan.FindKernel("BlockScanAdd");
  16. shaderReduce = shaders.blockReducePart;
  17. kernelReduce = shaderReduce.FindKernel("BlockReducePart");
  18. }
  19. public void Execute(CommandBuffer cmd, GraphicsBuffer buffer, uint inputKeysOffset, uint outputKeysOffset, uint scratchDataOffset, uint size)
  20. {
  21. if (size > kKeysPerGroup)
  22. {
  23. var num_groups_level_1 = Common.CeilDivide(size, kKeysPerGroup);
  24. // Do first round of part sum reduction.
  25. SetState(cmd, shaderReduce, kernelReduce, size, buffer,
  26. inputKeysOffset,
  27. scratchDataOffset,
  28. outputKeysOffset);
  29. cmd.DispatchCompute(shaderReduce, kernelReduce, (int)num_groups_level_1, 1, 1);
  30. if (num_groups_level_1 > kKeysPerGroup)
  31. {
  32. var num_groups_level_2 = Common.CeilDivide(num_groups_level_1, kKeysPerGroup);
  33. // Do second round of part sum reduction.
  34. SetState(cmd, shaderReduce, kernelReduce, num_groups_level_1, buffer,
  35. scratchDataOffset,
  36. scratchDataOffset + num_groups_level_1,
  37. scratchDataOffset);
  38. cmd.DispatchCompute(shaderReduce, kernelReduce, (int)num_groups_level_2, 1, 1);
  39. // Scan level 2 inplace.
  40. Common.EnableKeyword(cmd, shaderScan, "ADD_PART_SUM", false);
  41. SetState(cmd, shaderScan, kernelScan, num_groups_level_2, buffer,
  42. scratchDataOffset + num_groups_level_1,
  43. scratchDataOffset,
  44. scratchDataOffset + num_groups_level_1);
  45. cmd.DispatchCompute(shaderScan, kernelScan, 1, 1, 1);
  46. }
  47. // Scan and add level 2 back to level 1.
  48. {
  49. Common.EnableKeyword(cmd, shaderScan, "ADD_PART_SUM", num_groups_level_1 > kKeysPerGroup);
  50. SetState(cmd, shaderScan, kernelScan, num_groups_level_1, buffer,
  51. scratchDataOffset,
  52. scratchDataOffset + num_groups_level_1,
  53. scratchDataOffset);
  54. var num_groups_scan_level_1 = Common.CeilDivide(num_groups_level_1, kKeysPerGroup);
  55. cmd.DispatchCompute(shaderScan, kernelScan, (int)num_groups_scan_level_1, 1, 1);
  56. }
  57. }
  58. // Scan and add level 1 back.
  59. {
  60. Common.EnableKeyword(cmd, shaderScan, "ADD_PART_SUM", size > kKeysPerGroup);
  61. SetState(cmd, shaderScan, kernelScan, size, buffer,
  62. inputKeysOffset,
  63. scratchDataOffset,
  64. outputKeysOffset);
  65. var num_groups_scan_level_0 = Common.CeilDivide(size, kKeysPerGroup);
  66. cmd.DispatchCompute(shaderScan, kernelScan, (int)num_groups_scan_level_0, 1, 1);
  67. }
  68. }
  69. void SetState(
  70. CommandBuffer cmd,
  71. ComputeShader shader, int kernelIndex, uint size, GraphicsBuffer buffer,
  72. uint inputKeysOffset, uint scratchDataOffset, uint outputKeysOffset)
  73. {
  74. cmd.SetComputeIntParam(shader, SID.g_constants_num_keys, (int)size);
  75. cmd.SetComputeIntParam(shader, SID.g_constants_input_keys_offset, (int)inputKeysOffset);
  76. cmd.SetComputeIntParam(shader, SID.g_constants_part_sums_offset, (int)scratchDataOffset);
  77. cmd.SetComputeIntParam(shader, SID.g_constants_output_keys_offset, (int)outputKeysOffset);
  78. cmd.SetComputeBufferParam(shader, kernelIndex, SID.g_buffer, buffer);
  79. }
  80. public ulong GetScratchDataSizeInDwords(uint size)
  81. {
  82. if (size <= kKeysPerGroup)
  83. {
  84. return 0;
  85. }
  86. else
  87. {
  88. var sizeLevel1 = Common.CeilDivide(size, kKeysPerGroup);
  89. if (sizeLevel1 <= kKeysPerGroup)
  90. {
  91. return sizeLevel1;
  92. }
  93. else
  94. {
  95. var sizeLevel2 = Common.CeilDivide(sizeLevel1, kKeysPerGroup);
  96. return (sizeLevel1 + sizeLevel2);
  97. }
  98. }
  99. }
  100. }
  101. }