HzbGenPyramid.ankiprog 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright (C) 2009-present, 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 REDUCTION_TYPE 0 1 // 0: min 1: max
  6. #pragma anki mutator MIN_MAX_SAMPLER 0 1
  7. #pragma anki technique comp
  8. #include <AnKi/Shaders/Common.hlsl>
  9. struct Constants
  10. {
  11. Vec2 m_invSrcTexSize;
  12. U32 m_threadGroupCount;
  13. U32 m_mipmapCount;
  14. };
  15. ANKI_FAST_CONSTANTS(Constants, g_consts)
  16. globallycoherent RWStructuredBuffer<U32> g_spdCounter : register(u0);
  17. globallycoherent RWTexture2D<Vec4> g_dstStorageTextures[kMaxMipsSinglePassDownsamplerCanProduce] : register(u1);
  18. Texture2D<Vec4> g_srcTex : register(t0);
  19. #if MIN_MAX_SAMPLER
  20. SamplerState g_minMaxAnyClampSampler : register(s0);
  21. #else
  22. SamplerState g_linearAnyClampSampler : register(s0);
  23. #endif
  24. // Include SPD
  25. #define A_GPU 1
  26. #define A_HLSL 1
  27. #include <ThirdParty/FidelityFX/ffx_a.h>
  28. groupshared AU1 s_spdCounter;
  29. groupshared AF1 s_spdIntermediateR[16][16];
  30. AF4 SpdLoadSourceImage(AU2 p, AU1 slice)
  31. {
  32. ANKI_MAYBE_UNUSED(slice);
  33. const AF2 uv = p * g_consts.m_invSrcTexSize + g_consts.m_invSrcTexSize;
  34. #if MIN_MAX_SAMPLER
  35. const F32 f = g_srcTex.SampleLevel(g_minMaxAnyClampSampler, uv, 0.0).r;
  36. #else
  37. Vec4 samples = g_srcTex.GatherRed(g_linearAnyClampSampler, uv);
  38. # if REDUCTION_TYPE == 0
  39. const F32 f = min4(samples);
  40. # else
  41. const F32 f = max4(samples);
  42. # endif
  43. #endif
  44. return AF4(f, 0.0, 0.0, 0.0);
  45. }
  46. AF4 SpdLoad(AU2 p, AU1 slice)
  47. {
  48. ANKI_MAYBE_UNUSED(slice);
  49. return AF4(g_dstStorageTextures[5][p].r, 0.0, 0.0, 0.0);
  50. }
  51. void SpdStore(AU2 p, AF4 value, AU1 mip, AU1 slice)
  52. {
  53. ANKI_MAYBE_UNUSED(slice);
  54. g_dstStorageTextures[mip][p] = Vec4(value.x, 0.0, 0.0, 0.0);
  55. }
  56. void SpdIncreaseAtomicCounter(AU1 slice)
  57. {
  58. ANKI_MAYBE_UNUSED(slice);
  59. InterlockedAdd(g_spdCounter[0], 1u, s_spdCounter);
  60. }
  61. AU1 SpdGetAtomicCounter()
  62. {
  63. return s_spdCounter;
  64. }
  65. void SpdResetAtomicCounter(AU1 slice)
  66. {
  67. ANKI_MAYBE_UNUSED(slice);
  68. g_spdCounter[0] = 0u;
  69. }
  70. AF4 SpdLoadIntermediate(AU1 x, AU1 y)
  71. {
  72. return AF4(s_spdIntermediateR[x][y], 0.0, 0.0, 0.0);
  73. }
  74. void SpdStoreIntermediate(AU1 x, AU1 y, AF4 value)
  75. {
  76. s_spdIntermediateR[x][y] = value.x;
  77. }
  78. AF4 SpdReduce4(AF4 v0, AF4 v1, AF4 v2, AF4 v3)
  79. {
  80. #if REDUCTION_TYPE == 0
  81. const F32 value = min4(v0.x, v1.x, v2.x, v3.x);
  82. #else
  83. const F32 value = max4(v0.x, v1.x, v2.x, v3.x);
  84. #endif
  85. return AF4(value, 0.0, 0.0, 0.0);
  86. }
  87. #define SPD_LINEAR_SAMPLER 1
  88. #include <ThirdParty/FidelityFX/ffx_spd.h>
  89. [numthreads(256, 1, 1)] void main(UVec3 svGroupId : SV_GROUPID, U32 svGroupIndex : SV_GROUPINDEX)
  90. {
  91. const U32 slice = 0u;
  92. const UVec2 offset = UVec2(0, 0);
  93. SpdDownsample(AU2(svGroupId.xy), AU1(svGroupIndex), AU1(g_consts.m_mipmapCount), AU1(g_consts.m_threadGroupCount), slice, offset);
  94. }