RenderComponent.cpp 8.3 KB

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