HairCommon.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Atom/RHI/Factory.h>
  9. #include <Atom/RHI/RHIUtils.h>
  10. #include <Atom/RPI.Public/Shader/Shader.h>
  11. #include <Atom/RPI.Public/Image/StreamingImage.h>
  12. #include <Atom/RPI.Public/RPIUtils.h>
  13. #include <Atom/RPI.Reflect/Buffer/BufferAssetView.h>
  14. // Hair specific
  15. #include <Rendering/HairCommon.h>
  16. namespace AZ
  17. {
  18. namespace Render
  19. {
  20. namespace Hair
  21. {
  22. //!=====================================================================================
  23. //!
  24. //! Utility Functions
  25. //!
  26. //!=====================================================================================
  27. // [To Do] examine if most of these functions can become global in RPI
  28. //! Utility function to generate the Srg given the shader and the desired Srg name to be associated to.
  29. //! If several shaders are sharing the same Srg (for example perView, perScene), it is enough to
  30. //! create the Srg by associating it with a single shader and since the GPU signature and the data
  31. //! are referring to the same shared description (preferable set in an [SrgDeclaration].aszli file)
  32. //! The association with all shaders will work properly.
  33. Data::Instance<RPI::ShaderResourceGroup> UtilityClass::CreateShaderResourceGroup(
  34. Data::Instance<RPI::Shader> shader,
  35. const char* shaderResourceGroupId,
  36. [[maybe_unused]] const char* moduleName)
  37. {
  38. Data::Instance<RPI::ShaderResourceGroup> srg = RPI::ShaderResourceGroup::Create(shader->GetAsset(), AZ::Name{ shaderResourceGroupId });
  39. if (!srg)
  40. {
  41. AZ_Error(moduleName, false, "Failed to create shader resource group");
  42. return nullptr;
  43. }
  44. return srg;
  45. }
  46. //! If srg is nullptr the index handle will NOT be set.
  47. //! This can be useful when creating a constant buffer or an image.
  48. Data::Instance<RPI::Buffer> UtilityClass::CreateBuffer(
  49. [[maybe_unused]] const char* warningHeader,
  50. SrgBufferDescriptor& bufferDesc,
  51. Data::Instance<RPI::ShaderResourceGroup> srg)
  52. {
  53. // If srg is provided, match the shader Srg bind index (returned via the descriptor)
  54. if (srg)
  55. { // Not always do we want to associate Srg when creating a buffer
  56. bufferDesc.m_resourceShaderIndex = srg->FindShaderInputBufferIndex(bufferDesc.m_paramNameInSrg).GetIndex();
  57. if (bufferDesc.m_resourceShaderIndex == uint32_t(-1))
  58. {
  59. AZ_Error(warningHeader, false, "Failed to find shader input index for [%s] in the SRG.",
  60. bufferDesc.m_paramNameInSrg.GetCStr());
  61. return nullptr;
  62. }
  63. }
  64. // Descriptor setting
  65. RPI::CommonBufferDescriptor desc;
  66. desc.m_elementFormat = bufferDesc.m_elementFormat;
  67. desc.m_poolType = bufferDesc.m_poolType;;
  68. desc.m_elementSize = bufferDesc.m_elementSize;
  69. desc.m_bufferName = bufferDesc.m_bufferName.GetCStr();
  70. desc.m_byteCount = (uint64_t)bufferDesc.m_elementCount * bufferDesc.m_elementSize;
  71. desc.m_bufferData = nullptr; // set during asset load - use Update
  72. // Buffer creation
  73. return RPI::BufferSystemInterface::Get()->CreateBufferFromCommonPool(desc);
  74. }
  75. bool UtilityClass::BindBufferToSrg(
  76. [[maybe_unused]] const char* warningHeader,
  77. Data::Instance<RPI::Buffer> buffer,
  78. SrgBufferDescriptor& bufferDesc,
  79. Data::Instance<RPI::ShaderResourceGroup> srg)
  80. {
  81. if (!buffer)
  82. {
  83. AZ_Error(warningHeader, false, "Trying to bind a null buffer");
  84. return false;
  85. }
  86. RHI::ShaderInputBufferIndex bufferIndex = srg->FindShaderInputBufferIndex(bufferDesc.m_paramNameInSrg);
  87. if (!bufferIndex.IsValid())
  88. {
  89. AZ_Error(warningHeader, false, "Failed to find shader input index for [%s] in the SRG.",
  90. bufferDesc.m_paramNameInSrg.GetCStr());
  91. return false;
  92. }
  93. if (!srg->SetBufferView(bufferIndex, buffer->GetBufferView()))
  94. {
  95. AZ_Error(warningHeader, false, "Failed to bind buffer view for [%s]", bufferDesc.m_bufferName.GetCStr());
  96. return false;
  97. }
  98. return true;
  99. }
  100. Data::Instance<RPI::Buffer> UtilityClass::CreateBufferAndBindToSrg(
  101. const char* warningHeader,
  102. SrgBufferDescriptor& bufferDesc,
  103. Data::Instance<RPI::ShaderResourceGroup> srg)
  104. {
  105. // Buffer creation
  106. Data::Instance<RPI::Buffer> buffer = CreateBuffer(warningHeader, bufferDesc, srg);
  107. if (!BindBufferToSrg(warningHeader, buffer, bufferDesc, srg))
  108. {
  109. return nullptr;
  110. }
  111. return buffer;
  112. }
  113. Data::Instance<RHI::ImagePool> UtilityClass::CreateImagePool(RHI::ImagePoolDescriptor& imagePoolDesc)
  114. {
  115. Data::Instance<RHI::ImagePool> imagePool = aznew RHI::ImagePool;
  116. RHI::ResultCode result = imagePool->Init(imagePoolDesc);
  117. if (result != RHI::ResultCode::Success)
  118. {
  119. AZ_Error("CreateImagePool", false, "Failed to create or initialize image pool");
  120. return nullptr;
  121. }
  122. return imagePool;
  123. }
  124. Data::Instance<RHI::Image> UtilityClass::CreateImage2D(
  125. RHI::ImagePool* imagePool, RHI::ImageDescriptor& imageDesc)
  126. {
  127. Data::Instance<RHI::Image> rhiImage = aznew RHI::Image;
  128. RHI::ImageInitRequest request;
  129. request.m_image = rhiImage.get();
  130. request.m_descriptor = imageDesc;
  131. RHI::ResultCode result = imagePool->InitImage(request);
  132. if (result != RHI::ResultCode::Success)
  133. {
  134. AZ_Error("CreateImage2D", false, "Failed to create or initialize image");
  135. return nullptr;
  136. }
  137. return rhiImage;
  138. }
  139. } // namespace Hair
  140. } // namespace Render
  141. } // namespace AZ