RenderComponent.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. #include <AnKi/Scene/Components/RenderComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. #include <AnKi/Resource/ImageResource.h>
  8. #include <AnKi/Resource/ResourceManager.h>
  9. #include <AnKi/Util/Logger.h>
  10. namespace anki {
  11. ANKI_SCENE_COMPONENT_STATICS(RenderComponent)
  12. void RenderComponent::allocateAndSetupUniforms(const MaterialResourcePtr& mtl, const RenderQueueDrawContext& ctx,
  13. ConstWeakArray<Mat4> transforms, ConstWeakArray<Mat4> prevTransforms,
  14. StagingGpuMemoryManager& alloc)
  15. {
  16. ANKI_ASSERT(transforms.getSize() <= MAX_INSTANCE_COUNT);
  17. ANKI_ASSERT(prevTransforms.getSize() == transforms.getSize());
  18. const MaterialVariant& variant = mtl->getOrCreateVariant(ctx.m_key);
  19. const U32 set = mtl->getDescriptorSetIndex();
  20. // Allocate and bind uniform memory
  21. const U32 perDrawUboSize = variant.getPerDrawUniformBlockSize();
  22. const U32 perInstanceUboSize = variant.getPerInstanceUniformBlockSize(transforms.getSize());
  23. StagingGpuMemoryToken token;
  24. void* const perDrawUniformsBegin =
  25. (perDrawUboSize != 0) ? alloc.allocateFrame(perDrawUboSize, StagingGpuMemoryType::UNIFORM, token) : nullptr;
  26. const void* const perDrawUniformsEnd = static_cast<U8*>(perDrawUniformsBegin) + perDrawUboSize;
  27. StagingGpuMemoryToken token1;
  28. void* const perInstanceUniformsBegin =
  29. (perInstanceUboSize != 0) ? alloc.allocateFrame(perInstanceUboSize, StagingGpuMemoryType::UNIFORM, token1)
  30. : nullptr;
  31. const void* const perInstanceUniformsEnd = static_cast<U8*>(perInstanceUniformsBegin) + perInstanceUboSize;
  32. if(perDrawUboSize)
  33. {
  34. ctx.m_commandBuffer->bindUniformBuffer(set, mtl->getPerDrawUniformBlockBinding(), token.m_buffer,
  35. token.m_offset, token.m_range);
  36. }
  37. if(perInstanceUboSize)
  38. {
  39. ctx.m_commandBuffer->bindUniformBuffer(set, mtl->getPerInstanceUniformBlockBinding(), token1.m_buffer,
  40. token1.m_offset, token1.m_range);
  41. }
  42. // Iterate variables
  43. for(const MaterialVariable& mvar : mtl->getVariables())
  44. {
  45. if(!variant.isVariableActive(mvar))
  46. {
  47. continue;
  48. }
  49. switch(mvar.getDataType())
  50. {
  51. case ShaderVariableDataType::F32:
  52. {
  53. const F32 val = mvar.getValue<F32>();
  54. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  55. break;
  56. }
  57. case ShaderVariableDataType::VEC2:
  58. {
  59. const Vec2 val = mvar.getValue<Vec2>();
  60. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  61. break;
  62. }
  63. case ShaderVariableDataType::VEC3:
  64. {
  65. switch(mvar.getBuiltin())
  66. {
  67. case BuiltinMaterialVariableId::NONE:
  68. {
  69. const Vec3 val = mvar.getValue<Vec3>();
  70. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  71. break;
  72. }
  73. case BuiltinMaterialVariableId::CAMERA_POSITION:
  74. {
  75. const Vec3 val = ctx.m_cameraTransform.getTranslationPart().xyz();
  76. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  77. break;
  78. }
  79. default:
  80. ANKI_ASSERT(0);
  81. }
  82. break;
  83. }
  84. case ShaderVariableDataType::VEC4:
  85. {
  86. const Vec4 val = mvar.getValue<Vec4>();
  87. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  88. break;
  89. }
  90. case ShaderVariableDataType::MAT3:
  91. {
  92. switch(mvar.getBuiltin())
  93. {
  94. case BuiltinMaterialVariableId::NONE:
  95. {
  96. const Mat3 val = mvar.getValue<Mat3>();
  97. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  98. break;
  99. }
  100. case BuiltinMaterialVariableId::NORMAL_MATRIX:
  101. {
  102. ANKI_ASSERT(transforms.getSize() > 0);
  103. Array<Mat3, MAX_INSTANCE_COUNT> normMats;
  104. for(U32 i = 0; i < transforms.getSize(); i++)
  105. {
  106. const Mat4 mv = ctx.m_viewMatrix * transforms[i];
  107. normMats[i] = mv.getRotationPart();
  108. normMats[i].reorthogonalize();
  109. }
  110. variant.writeShaderBlockMemory(mvar, &normMats[0], transforms.getSize(),
  111. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  112. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  113. break;
  114. }
  115. case BuiltinMaterialVariableId::ROTATION_MATRIX:
  116. {
  117. ANKI_ASSERT(transforms.getSize() > 0);
  118. Array<Mat3, MAX_INSTANCE_COUNT> rots;
  119. for(U32 i = 0; i < transforms.getSize(); i++)
  120. {
  121. rots[i] = transforms[i].getRotationPart();
  122. }
  123. variant.writeShaderBlockMemory(mvar, &rots[0], transforms.getSize(),
  124. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  125. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  126. break;
  127. }
  128. case BuiltinMaterialVariableId::CAMERA_ROTATION_MATRIX:
  129. {
  130. const Mat3 rot = ctx.m_cameraTransform.getRotationPart();
  131. variant.writeShaderBlockMemory(mvar, &rot, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  132. break;
  133. }
  134. default:
  135. ANKI_ASSERT(0);
  136. }
  137. break;
  138. }
  139. case ShaderVariableDataType::MAT4:
  140. {
  141. switch(mvar.getBuiltin())
  142. {
  143. case BuiltinMaterialVariableId::NONE:
  144. {
  145. const Mat4 val = mvar.getValue<Mat4>();
  146. variant.writeShaderBlockMemory(mvar, &val, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  147. break;
  148. }
  149. case BuiltinMaterialVariableId::MODEL_VIEW_PROJECTION_MATRIX:
  150. {
  151. ANKI_ASSERT(transforms.getSize() > 0);
  152. Array<Mat4, MAX_INSTANCE_COUNT> mvp;
  153. for(U32 i = 0; i < transforms.getSize(); i++)
  154. {
  155. mvp[i] = ctx.m_viewProjectionMatrix * transforms[i];
  156. }
  157. variant.writeShaderBlockMemory(mvar, &mvp[0], transforms.getSize(),
  158. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  159. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  160. break;
  161. }
  162. case BuiltinMaterialVariableId::PREVIOUS_MODEL_VIEW_PROJECTION_MATRIX:
  163. {
  164. ANKI_ASSERT(prevTransforms.getSize() > 0);
  165. Array<Mat4, MAX_INSTANCE_COUNT> mvp;
  166. for(U32 i = 0; i < prevTransforms.getSize(); i++)
  167. {
  168. mvp[i] = ctx.m_previousViewProjectionMatrix * prevTransforms[i];
  169. }
  170. variant.writeShaderBlockMemory(mvar, &mvp[0], prevTransforms.getSize(),
  171. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  172. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  173. break;
  174. }
  175. case BuiltinMaterialVariableId::MODEL_VIEW_MATRIX:
  176. {
  177. ANKI_ASSERT(transforms.getSize() > 0);
  178. Array<Mat4, MAX_INSTANCE_COUNT> mv;
  179. for(U32 i = 0; i < transforms.getSize(); i++)
  180. {
  181. mv[i] = ctx.m_viewMatrix * transforms[i];
  182. }
  183. variant.writeShaderBlockMemory(mvar, &mv[0], transforms.getSize(),
  184. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  185. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  186. break;
  187. }
  188. case BuiltinMaterialVariableId::MODEL_MATRIX:
  189. {
  190. ANKI_ASSERT(transforms.getSize() > 0);
  191. variant.writeShaderBlockMemory(mvar, &transforms[0], transforms.getSize(),
  192. (mvar.isInstanced()) ? perInstanceUniformsBegin : perDrawUniformsBegin,
  193. (mvar.isInstanced()) ? perInstanceUniformsEnd : perDrawUniformsEnd);
  194. break;
  195. }
  196. case BuiltinMaterialVariableId::VIEW_PROJECTION_MATRIX:
  197. {
  198. ANKI_ASSERT(transforms.getSize() == 0 && "Cannot have transform");
  199. variant.writeShaderBlockMemory(mvar, &ctx.m_viewProjectionMatrix, 1, perDrawUniformsBegin,
  200. perDrawUniformsEnd);
  201. break;
  202. }
  203. case BuiltinMaterialVariableId::VIEW_MATRIX:
  204. {
  205. variant.writeShaderBlockMemory(mvar, &ctx.m_viewMatrix, 1, perDrawUniformsBegin, perDrawUniformsEnd);
  206. break;
  207. }
  208. default:
  209. ANKI_ASSERT(0);
  210. }
  211. break;
  212. }
  213. case ShaderVariableDataType::TEXTURE_2D:
  214. case ShaderVariableDataType::TEXTURE_2D_ARRAY:
  215. case ShaderVariableDataType::TEXTURE_3D:
  216. case ShaderVariableDataType::TEXTURE_CUBE:
  217. {
  218. ctx.m_commandBuffer->bindTexture(set, mvar.getOpaqueBinding(),
  219. mvar.getValue<ImageResourcePtr>()->getTextureView());
  220. break;
  221. }
  222. case ShaderVariableDataType::SAMPLER:
  223. {
  224. switch(mvar.getBuiltin())
  225. {
  226. case BuiltinMaterialVariableId::GLOBAL_SAMPLER:
  227. ctx.m_commandBuffer->bindSampler(set, mvar.getOpaqueBinding(), ctx.m_sampler);
  228. break;
  229. default:
  230. ANKI_ASSERT(0);
  231. }
  232. break;
  233. }
  234. default:
  235. ANKI_ASSERT(0);
  236. } // end switch
  237. }
  238. }
  239. } // end namespace anki