Common.hlsl 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. // This file contains common code for all shaders. It's optional but it's recomended to include it
  6. #pragma once
  7. #if defined(__INTELLISENSE__)
  8. # include <AnKi/Shaders/Intellisense.hlsl>
  9. #else
  10. # include <AnKi/Shaders/Include/Common.h>
  11. #endif
  12. // Common constants
  13. constexpr F32 kEpsilonF32 = 0.000001f;
  14. constexpr F16 kEpsilonF16 = (F16)0.0001f; // Divisions by this should be OK according to http://weitz.de/ieee
  15. template<typename T>
  16. T getEpsilon();
  17. template<>
  18. F32 getEpsilon()
  19. {
  20. return kEpsilonF32;
  21. }
  22. template<>
  23. F16 getEpsilon()
  24. {
  25. return kEpsilonF16;
  26. }
  27. constexpr U32 kMaxU32 = 0xFFFFFFFFu;
  28. constexpr I32 kMinI32 = -2147483648;
  29. constexpr I32 kMaxI32 = 2147483647;
  30. constexpr F32 kMaxF32 = 3.402823e+38;
  31. constexpr F32 kMinF32 = -3.402823e+38;
  32. constexpr F16 kMaxF16 = (F16)65504.0;
  33. template<typename T>
  34. T getMaxNumericLimit();
  35. template<>
  36. F32 getMaxNumericLimit()
  37. {
  38. return kMaxF32;
  39. }
  40. template<>
  41. F16 getMaxNumericLimit()
  42. {
  43. return kMaxF16;
  44. }
  45. template<>
  46. U32 getMaxNumericLimit()
  47. {
  48. return kMaxU32;
  49. }
  50. constexpr F32 kPi = 3.14159265358979323846;
  51. constexpr F32 k2Pi = 2.0 * kPi;
  52. constexpr F32 kHalfPi = kPi / 2.0;
  53. constexpr F32 kNaN = 0.0 / 0.0;
  54. constexpr F32 kMaxHistoryLength = 16.0;
  55. struct Barycentrics
  56. {
  57. Vec2 m_value;
  58. };
  59. #if ANKI_GR_BACKEND_VULKAN
  60. # define ANKI_FAST_CONSTANTS(type, var) [[vk::push_constant]] ConstantBuffer<type> var;
  61. #else
  62. # define ANKI_FAST_CONSTANTS(type, var) ConstantBuffer<type> var : register(b0, ANKI_CONCATENATE(space, ANKI_D3D_FAST_CONSTANTS_SPACE));
  63. #endif
  64. #if ANKI_GR_BACKEND_VULKAN
  65. # define ANKI_SHADER_RECORD_CONSTANTS(type, var) [[vk::shader_record_ext]] ConstantBuffer<type> var : register(b0, space3001);
  66. #else
  67. # define ANKI_SHADER_RECORD_CONSTANTS(type, var) \
  68. ConstantBuffer<type> var : register(b0, ANKI_CONCATENATE(space, ANKI_D3D_SHADER_RECORD_CONSTANTS_SPACE));
  69. #endif
  70. // This is the implementation of gl_DrawID for both D3D anv VK
  71. #if ANKI_VERTEX_SHADER
  72. # if ANKI_GR_BACKEND_VULKAN
  73. # define SpvDrawIndex 4426
  74. [[vk::ext_builtin_input(SpvDrawIndex)]] const static U32 gl_DrawID;
  75. # else
  76. struct U32Struct
  77. {
  78. U32 m_data;
  79. };
  80. ConstantBuffer<U32Struct> g_drawIdConstant : register(b0, ANKI_CONCATENATE(space, ANKI_D3D_DRAW_ID_CONSTANT_SPACE));
  81. # define gl_DrawID g_drawIdConstant.m_data
  82. # endif
  83. #endif
  84. #if ANKI_GR_BACKEND_VULKAN
  85. # define ANKI_BINDLESS(texType, compType) \
  86. [[vk::binding(0, ANKI_VK_BINDLESS_TEXTURES_DESCRIPTOR_SET)]] Texture##texType<compType> g_bindlessTextures##texType##compType[]; \
  87. Texture##texType<compType> getBindlessTexture##texType##compType(U32 idx) \
  88. { \
  89. return g_bindlessTextures##texType##compType[idx]; \
  90. } \
  91. Texture##texType<compType> getBindlessTextureNonUniformIndex##texType##compType(U32 idx) \
  92. { \
  93. return g_bindlessTextures##texType##compType[NonUniformResourceIndex(idx)]; \
  94. }
  95. #else
  96. # define ANKI_BINDLESS(texType, compType) \
  97. Texture##texType<compType> getBindlessTexture##texType##compType(U32 idx) \
  98. { \
  99. Texture##texType<compType> tex = ResourceDescriptorHeap[idx]; \
  100. return tex; \
  101. } \
  102. Texture##texType<compType> getBindlessTextureNonUniformIndex##texType##compType(U32 idx) \
  103. { \
  104. Texture##texType<compType> tex = ResourceDescriptorHeap[NonUniformResourceIndex(idx)]; \
  105. return tex; \
  106. }
  107. #endif
  108. #define ANKI_BINDLESS2(texType) \
  109. ANKI_BINDLESS(texType, UVec4) \
  110. ANKI_BINDLESS(texType, IVec4) \
  111. ANKI_BINDLESS(texType, Vec4)
  112. #define ANKI_BINDLESS3() \
  113. ANKI_BINDLESS2(2D) \
  114. ANKI_BINDLESS2(Cube) \
  115. ANKI_BINDLESS2(2DArray) \
  116. ANKI_BINDLESS2(3D)
  117. ANKI_BINDLESS3()
  118. template<typename T>
  119. U32 getStructuredBufferElementCount(T x)
  120. {
  121. U32 size, stride;
  122. x.GetDimensions(size, stride);
  123. return size;
  124. }
  125. template<typename T>
  126. U32 checkStructuredBuffer(T buff, U32 idx)
  127. {
  128. ANKI_ASSERT(idx < getStructuredBufferElementCount(buff));
  129. return idx;
  130. }
  131. // Safely access a structured buffer. Throw an assertion if it's out of bounds
  132. #define SBUFF(buff, idx) buff[checkStructuredBuffer(buff, idx)]
  133. template<typename TStruct, typename TBab>
  134. U32 checkBab(TBab bab, U32 offset)
  135. {
  136. U32 babSize;
  137. bab.GetDimensions(babSize);
  138. ANKI_ASSERT(offset + sizeof(TStruct) <= babSize);
  139. return offset;
  140. }
  141. // Savely access a ByteAddressBuffer
  142. #define BAB_LOAD(bab, type, offset) bab.Load<type>(checkBab<type>(bab, offset))
  143. #define BAB_STORE(bab, type, offset, data) bab.Store<type>(checkBab<type>(bab, offset), data)
  144. #define CHECK_TEXTURE_3D(textureType) \
  145. UVec3 checkTexture(textureType tex, UVec3 coords) \
  146. { \
  147. UVec3 size; \
  148. tex.GetDimensions(size.x, size.y, size.z); \
  149. ANKI_ASSERT(coords.x < size.x && coords.y < size.y && coords.z < size.z); \
  150. return coords; \
  151. }
  152. #define CHECK_TEXTURE_2D(textureType) \
  153. UVec2 checkTexture(textureType tex, UVec2 coords) \
  154. { \
  155. UVec2 size; \
  156. tex.GetDimensions(size.x, size.y); \
  157. ANKI_ASSERT(coords.x < size.x && coords.y < size.y); \
  158. return coords; \
  159. }
  160. #define CHECK_TEXTURE_1(vectorType) \
  161. CHECK_TEXTURE_3D(RWTexture3D<vectorType>) \
  162. CHECK_TEXTURE_3D(Texture3D<vectorType>) \
  163. CHECK_TEXTURE_2D(RWTexture2D<vectorType>) \
  164. CHECK_TEXTURE_2D(Texture2D<vectorType>)
  165. #define CHECK_TEXTURE_2(componentCount) \
  166. CHECK_TEXTURE_1(Vec##componentCount) \
  167. CHECK_TEXTURE_1(UVec##componentCount) \
  168. CHECK_TEXTURE_1(IVec##componentCount)
  169. #define CHECK_TEXTURE_3() \
  170. CHECK_TEXTURE_2(2) \
  171. CHECK_TEXTURE_2(3) \
  172. CHECK_TEXTURE_2(4) \
  173. CHECK_TEXTURE_1(F32) \
  174. CHECK_TEXTURE_1(U32) \
  175. CHECK_TEXTURE_1(I32)
  176. CHECK_TEXTURE_3()
  177. #undef CHECK_TEXTURE_3
  178. #undef CHECK_TEXTURE_2
  179. #undef CHECK_TEXTURE_1
  180. #undef CHECK_TEXTURE_2D
  181. #undef CHECK_TEXTURE_3D
  182. /// Safely access a UAV or SRV texture. Throw an assertion if it's out of bounds
  183. #define TEX(tex, coords) tex[checkTexture(tex, coords)]
  184. // Need extra decoration for per-primitive stuff in Vulkan. Remove when https://github.com/microsoft/DirectXShaderCompiler/issues/6862 is fixed
  185. #if ANKI_GR_BACKEND_VULKAN
  186. # define SpvCapabilityMeshShadingEXT 5283
  187. # define SpvDecorationPerPrimitiveEXT 5271
  188. # define ANKI_PER_PRIMITIVE_VAR [[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_capability(SpvCapabilityMeshShadingEXT)]]
  189. # define ANKI_PER_PRIMITIVE_MEMBER \
  190. [[vk::ext_extension("SPV_EXT_mesh_shader")]] [[vk::ext_decorate(SpvDecorationPerPrimitiveEXT)]] [[vk::ext_capability( \
  191. SpvCapabilityMeshShadingEXT)]]
  192. #else
  193. # define ANKI_PER_PRIMITIVE_VAR
  194. # define ANKI_PER_PRIMITIVE_MEMBER
  195. #endif
  196. #if ANKI_GR_BACKEND_VULKAN && ANKI_CLOSEST_HIT_SHADER
  197. # define SpvBuiltInHitTriangleVertexPositionsKHR 5335
  198. # define SpvCapabilityRayTracingPositionFetchKHR 5336
  199. [[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]] [[vk::ext_capability(SpvCapabilityRayTracingPositionFetchKHR)]] [[vk::ext_builtin_input(
  200. SpvBuiltInHitTriangleVertexPositionsKHR)]] const static Vec3 gl_HitTriangleVertexPositions[3];
  201. #endif
  202. #if ANKI_GR_BACKEND_VULKAN
  203. # define SpvRayQueryPositionFetchKHR 5391
  204. # define SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR 5340
  205. # define SpvRayQueryCandidateIntersectionKHR 0
  206. # define SpvRayQueryCommittedIntersectionKHR 1
  207. [[vk::ext_capability(SpvRayQueryPositionFetchKHR)]] [[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]] [[vk::ext_instruction(
  208. SpvOpRayQueryGetIntersectionTriangleVertexPositionsKHR)]] float3
  209. spvRayQueryGetIntersectionTriangleVertexPositionsKHR([[vk::ext_reference]] RayQuery<RAY_FLAG_FORCE_OPAQUE> query, int committed)[3];
  210. #endif
  211. #if ANKI_GR_BACKEND_VULKAN
  212. # define SpvDecorationRelaxedPrecision 0
  213. # define ANKI_RELAXED_PRECISION [[vk::ext_decorate(SpvDecorationRelaxedPrecision)]]
  214. #else
  215. # define ANKI_RELAXED_PRECISION
  216. #endif
  217. #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
  218. template<typename T>
  219. T uvToNdc(T uv)
  220. {
  221. T ndc = uv * 2.0 - 1.0;
  222. ndc.y *= -1.0;
  223. return ndc;
  224. }
  225. template<typename T>
  226. T ndcToUv(T ndc)
  227. {
  228. T uv = ndc * 0.5 + 0.5;
  229. uv.y = 1.0 - uv.y;
  230. return uv;
  231. }
  232. // Define min3, max3, min4, max4 functions
  233. #define DEFINE_COMPARISON(func, scalarType, vectorType) \
  234. scalarType func##4(vectorType##4 v) \
  235. { \
  236. return func(v.x, func(v.y, func(v.z, v.w))); \
  237. } \
  238. scalarType func##4(scalarType x, scalarType y, scalarType z, scalarType w) \
  239. { \
  240. return func(x, func(y, func(z, w))); \
  241. } \
  242. scalarType func##3(vectorType##3 v) \
  243. { \
  244. return func(v.x, func(v.y, v.z)); \
  245. } \
  246. scalarType func##3(scalarType x, scalarType y, scalarType z) \
  247. { \
  248. return func(x, func(y, z)); \
  249. } \
  250. scalarType func##2(vectorType##2 v) \
  251. { \
  252. return func(v.x, v.y); \
  253. }
  254. #define DEFINE_COMPARISON2(func) \
  255. DEFINE_COMPARISON(func, F32, Vec) \
  256. DEFINE_COMPARISON(func, I32, IVec) \
  257. DEFINE_COMPARISON(func, U32, UVec)
  258. DEFINE_COMPARISON2(min)
  259. DEFINE_COMPARISON2(max)
  260. #undef DEFINE_COMPARISON2
  261. #undef DEFINE_COMPARISON
  262. // Trick intellisense
  263. #if defined(__INTELLISENSE__)
  264. # define NOT_ZERO(exr) (1)
  265. #else
  266. # define NOT_ZERO(exr) ((exr) != 0)
  267. #endif
  268. template<typename T>
  269. T square(T x)
  270. {
  271. return x * x;
  272. }
  273. #define COMPUTE_ARGS \
  274. U32 svGroupIndex : \
  275. SV_GROUPINDEX, \
  276. UVec3 svGroupId : \
  277. SV_GROUPID, \
  278. UVec3 svDispatchThreadId : \
  279. SV_DISPATCHTHREADID, \
  280. UVec3 svGroupThreadId : SV_GROUPTHREADID