TilerMinMax.comp.glsl 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright (C) 2009-2017, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include "shaders/Common.glsl"
  6. const uint U32_MAX = 0xFFFFFFFFU;
  7. const uint WORKGROUP_SIZE_X = 16;
  8. const uint WORKGROUP_SIZE_Y = 16;
  9. // Every thread will read more pixels since the workgroup size is less than
  10. // the tile size.
  11. const uint PIXEL_READ_X = TILE_SIZE_X / WORKGROUP_SIZE_X;
  12. const uint PIXEL_READ_Y = TILE_SIZE_Y / WORKGROUP_SIZE_Y;
  13. layout(binding = 0) uniform sampler2D u_depthMap;
  14. layout(std430, binding = 0) writeonly buffer _blk
  15. {
  16. vec2 u_depthLimits[];
  17. };
  18. layout(local_size_x = WORKGROUP_SIZE_X, local_size_y = WORKGROUP_SIZE_Y, local_size_z = 1) in;
  19. shared uint g_minDepth;
  20. shared uint g_maxDepth;
  21. void main()
  22. {
  23. // Init
  24. g_minDepth = U32_MAX;
  25. g_maxDepth = 0U;
  26. memoryBarrierShared();
  27. barrier();
  28. // Get max/min depth
  29. ivec2 coord = ivec2(gl_GlobalInvocationID.xy) * ivec2(PIXEL_READ_X, PIXEL_READ_Y);
  30. float mind = 10.0;
  31. float maxd = -10.0;
  32. for(uint y = 0; y < PIXEL_READ_Y; ++y)
  33. {
  34. for(uint x = 0; x < PIXEL_READ_X; ++x)
  35. {
  36. float depth = texelFetch(u_depthMap, coord + ivec2(x, y), 0).r;
  37. mind = min(mind, depth);
  38. maxd = max(maxd, depth);
  39. }
  40. }
  41. uvec2 udepth = uvec2(vec2(mind, maxd) * float(U32_MAX));
  42. atomicMin(g_minDepth, udepth.x);
  43. atomicMax(g_maxDepth, udepth.y);
  44. memoryBarrierShared();
  45. barrier();
  46. // Write result
  47. if(gl_LocalInvocationIndex == 0)
  48. {
  49. uint idx = gl_WorkGroupID.y * TILES_COUNT_X + gl_WorkGroupID.x;
  50. u_depthLimits[idx] = vec2(g_minDepth, g_maxDepth) / float(U32_MAX);
  51. }
  52. }