DepthDownscale.ankiprog 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma anki mutator SAMPLE_RESOLVE_TYPE 0 1 2 // 0: average, 1: min, 2: max
  6. #pragma anki mutator WAVE_OPERATIONS 0 1
  7. #pragma anki mutator REDUCTION_SAMPLER 0 1
  8. #define AVG 0
  9. #define MIN 1
  10. #define MAX 2
  11. #pragma anki start comp
  12. #include <AnKi/Shaders/Common.glsl>
  13. layout(local_size_x = 256) in;
  14. layout(push_constant, std430) uniform b_pc
  15. {
  16. U32 u_workgroupCount;
  17. U32 u_mipmapCount;
  18. Vec2 u_srcTexSizeOverOne;
  19. U32 u_lastMipWidth;
  20. U32 u_padding[3u];
  21. };
  22. layout(set = 0, binding = 0) uniform image2D u_dstImages[12u];
  23. layout(set = 0, binding = 1) coherent uniform image2D u_dstImage5;
  24. layout(set = 0, binding = 2) coherent buffer b_atomic
  25. {
  26. U32 u_spdCounter;
  27. };
  28. layout(std430, set = 0, binding = 3) writeonly buffer b_cb
  29. {
  30. F32 u_clientBuf[];
  31. };
  32. layout(set = 0, binding = 4) uniform sampler u_reductionSampler; ///< Special sampler that can do min/max reduction.
  33. layout(set = 0, binding = 5) uniform texture2D u_srcTex;
  34. // Include SPD
  35. #define A_GPU 1
  36. #define A_GLSL 1
  37. #include <ThirdParty/FidelityFX/ffx_a.h>
  38. shared AU1 s_spdCounter;
  39. shared AF1 s_spdIntermediateR[16][16];
  40. F32 reduce(Vec4 depths)
  41. {
  42. #if SAMPLE_RESOLVE_TYPE == MIN
  43. return min(depths.x, min(depths.y, min(depths.z, depths.w)));
  44. #elif SAMPLE_RESOLVE_TYPE == MAX
  45. return max(depths.x, max(depths.y, max(depths.z, depths.w)));
  46. #elif SAMPLE_RESOLVE_TYPE == AVG
  47. return (depths.x + depths.y + depths.z + depths.w) * 0.25;
  48. #else
  49. # error See file
  50. #endif
  51. }
  52. AF4 SpdLoadSourceImage(AU2 p, AU1 slice)
  53. {
  54. const AF2 textureCoord = Vec2(p) * u_srcTexSizeOverOne + u_srcTexSizeOverOne;
  55. #if REDUCTION_SAMPLER == 1
  56. return AF4(textureLod(u_srcTex, u_reductionSampler, textureCoord, 0.0).r, 0.0, 0.0, 0.0);
  57. #else
  58. const Vec4 depths = textureGather(sampler2D(u_srcTex, u_reductionSampler), textureCoord, 0);
  59. return AF4(reduce(depths), 0.0, 0.0, 0.0);
  60. #endif
  61. }
  62. AF4 SpdLoad(AU2 p, AU1 slice)
  63. {
  64. return AF4(imageLoad(u_dstImage5, IVec2(p)).r, 0.0, 0.0, 0.0);
  65. }
  66. void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)
  67. {
  68. if(mip == 5u)
  69. {
  70. imageStore(u_dstImage5, IVec2(p), Vec4(value.x, 0.0, 0.0, 0.0));
  71. }
  72. else
  73. {
  74. imageStore(u_dstImages[mip], IVec2(p), Vec4(value.x, 0.0, 0.0, 0.0));
  75. }
  76. // Store the last mip to the buffer as well
  77. if(mip == u_mipmapCount - 1u)
  78. {
  79. const U32 idx = p.y * u_lastMipWidth + p.x;
  80. u_clientBuf[idx] = value.x;
  81. }
  82. }
  83. void SpdIncreaseAtomicCounter(AU1 slice)
  84. {
  85. s_spdCounter = atomicAdd(u_spdCounter, 1u);
  86. }
  87. AU1 SpdGetAtomicCounter()
  88. {
  89. return s_spdCounter;
  90. }
  91. void SpdResetAtomicCounter(AU1 slice)
  92. {
  93. u_spdCounter = 0u;
  94. }
  95. AF4 SpdLoadIntermediate(AU1 x, AU1 y)
  96. {
  97. return AF4(s_spdIntermediateR[x][y], 0.0, 0.0, 0.0);
  98. }
  99. void SpdStoreIntermediate(AU1 x, AU1 y, AF4 value)
  100. {
  101. s_spdIntermediateR[x][y] = value.x;
  102. }
  103. AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3)
  104. {
  105. return AF4(reduce(Vec4(v0.x, v1.x, v2.x, v3.x)), 0.0, 0.0, 0.0);
  106. }
  107. #define SPD_LINEAR_SAMPLER 1
  108. #if WAVE_OPERATIONS == 0
  109. # define SPD_NO_WAVE_OPERATIONS 1
  110. #endif
  111. #include <ThirdParty/FidelityFX/ffx_spd.h>
  112. void main()
  113. {
  114. const U32 slice = 0u;
  115. const UVec2 offset = UVec2(0u);
  116. SpdDownsample(AU2(gl_WorkGroupID.xy), AU1(gl_LocalInvocationIndex), AU1(u_mipmapCount), AU1(u_workgroupCount),
  117. slice, offset);
  118. }
  119. #pragma anki end