kernel_shader_sort.h 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * Copyright 2011-2017 Blender Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. CCL_NAMESPACE_BEGIN
  17. ccl_device void kernel_shader_sort(KernelGlobals *kg, ccl_local_param ShaderSortLocals *locals)
  18. {
  19. #ifndef __KERNEL_CUDA__
  20. int tid = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
  21. uint qsize = kernel_split_params.queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS];
  22. if (tid == 0) {
  23. kernel_split_params.queue_index[QUEUE_SHADER_SORTED_RAYS] = qsize;
  24. }
  25. uint offset = (tid / SHADER_SORT_LOCAL_SIZE) * SHADER_SORT_BLOCK_SIZE;
  26. if (offset >= qsize) {
  27. return;
  28. }
  29. int lid = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
  30. uint input = QUEUE_ACTIVE_AND_REGENERATED_RAYS * (kernel_split_params.queue_size);
  31. uint output = QUEUE_SHADER_SORTED_RAYS * (kernel_split_params.queue_size);
  32. ccl_local uint *local_value = &locals->local_value[0];
  33. ccl_local ushort *local_index = &locals->local_index[0];
  34. /* copy to local memory */
  35. for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
  36. uint idx = offset + i + lid;
  37. uint add = input + idx;
  38. uint value = (~0);
  39. if (idx < qsize) {
  40. int ray_index = kernel_split_state.queue_data[add];
  41. bool valid = (ray_index != QUEUE_EMPTY_SLOT) &&
  42. IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE);
  43. if (valid) {
  44. value = kernel_split_sd(sd, ray_index)->shader & SHADER_MASK;
  45. }
  46. }
  47. local_value[i + lid] = value;
  48. local_index[i + lid] = i + lid;
  49. }
  50. ccl_barrier(CCL_LOCAL_MEM_FENCE);
  51. /* skip sorting for cpu split kernel */
  52. # ifdef __KERNEL_OPENCL__
  53. /* bitonic sort */
  54. for (uint length = 1; length < SHADER_SORT_BLOCK_SIZE; length <<= 1) {
  55. for (uint inc = length; inc > 0; inc >>= 1) {
  56. for (uint ii = 0; ii < SHADER_SORT_BLOCK_SIZE; ii += SHADER_SORT_LOCAL_SIZE) {
  57. uint i = lid + ii;
  58. bool direction = ((i & (length << 1)) != 0);
  59. uint j = i ^ inc;
  60. ushort ioff = local_index[i];
  61. ushort joff = local_index[j];
  62. uint iKey = local_value[ioff];
  63. uint jKey = local_value[joff];
  64. bool smaller = (jKey < iKey) || (jKey == iKey && j < i);
  65. bool swap = smaller ^ (j < i) ^ direction;
  66. ccl_barrier(CCL_LOCAL_MEM_FENCE);
  67. local_index[i] = (swap) ? joff : ioff;
  68. local_index[j] = (swap) ? ioff : joff;
  69. ccl_barrier(CCL_LOCAL_MEM_FENCE);
  70. }
  71. }
  72. }
  73. # endif /* __KERNEL_OPENCL__ */
  74. /* copy to destination */
  75. for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
  76. uint idx = offset + i + lid;
  77. uint lidx = local_index[i + lid];
  78. uint outi = output + idx;
  79. uint ini = input + offset + lidx;
  80. uint value = local_value[lidx];
  81. if (idx < qsize) {
  82. kernel_split_state.queue_data[outi] = (value == (~0)) ? QUEUE_EMPTY_SLOT :
  83. kernel_split_state.queue_data[ini];
  84. }
  85. }
  86. #endif /* __KERNEL_CUDA__ */
  87. }
  88. CCL_NAMESPACE_END