DecalTextureArray.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #pragma once
  9. #include <AtomCore/Instance/Instance.h>
  10. #include <Atom/Feature/Utils/IndexableList.h>
  11. #include <AzCore/Asset/AssetCommon.h>
  12. #include <Atom/RHI.Reflect/ImageDescriptor.h>
  13. #include <Atom/RHI.Reflect/ImageSubresource.h>
  14. #include <AzCore/std/containers/span.h>
  15. #include <Atom/RPI.Public/Image/StreamingImage.h>
  16. namespace AZ
  17. {
  18. namespace RPI
  19. {
  20. class ImageMipChainAsset;
  21. class StreamingImageAsset;
  22. class MaterialAsset;
  23. }
  24. namespace Render
  25. {
  26. enum DecalMapType : uint32_t
  27. {
  28. DecalMapType_Diffuse,
  29. DecalMapType_Normal,
  30. DecalMapType_Num
  31. };
  32. //! Helper class used by DecalTextureArrayFeatureProcessor.
  33. //! Given a set of images (all with the same dimensions and format), it can pack them together into a single textureArray that can be sent to the GPU.
  34. //! Note that once textures are packed, this class will release any material references
  35. //! This might free memory if nothing else is holding onto them
  36. //! The class DOES keep note of which material asset ids were added, so it can load them again if necessary if the whole thing needs to be repacked
  37. class DecalTextureArray : public Data::AssetBus::MultiHandler
  38. {
  39. public:
  40. int AddMaterial(const AZ::Data::AssetId materialAssetId);
  41. void RemoveMaterial(const int index);
  42. size_t NumMaterials() const;
  43. AZ::Data::AssetId GetMaterialAssetId(const int index) const;
  44. // Packs all the added materials into one texture array per DecalMapType.
  45. void Pack();
  46. // Note that we pack each type into a separate texture array. This is because formats are
  47. // often different (BC5 for normals, BC7 for diffuse, etc)
  48. const Data::Instance<RPI::StreamingImage>& GetPackedTexture(const DecalMapType mapType) const;
  49. static bool IsValidDecalMaterial(RPI::MaterialAsset& materialAsset);
  50. private:
  51. struct MaterialData
  52. {
  53. AZ::Data::AssetId m_materialAssetId;
  54. // We will clear this to nullptr as soon as it is packed in order to release the memory. Note that we might need to reload it in order to repack it.
  55. AZ::Data::Asset<Data::AssetData> m_materialAssetData;
  56. };
  57. void OnAssetReady(Data::Asset<Data::AssetData> asset) override;
  58. // Returns the index of the material in the m_materials container. -1 if not present.
  59. int FindMaterial(const AZ::Data::AssetId materialAssetId) const;
  60. // packs the contents of the source images into a texture array readable by the GPU and returns it
  61. AZ::Data::Asset<AZ::RPI::ImageMipChainAsset> BuildPackedMipChainAsset(const DecalMapType mapType, const size_t numTexturesToCreate);
  62. RHI::ImageDescriptor CreatePackedImageDescriptor(const DecalMapType mapType, const uint16_t arraySize, const uint16_t mipLevels) const;
  63. uint16_t GetNumMipLevels(const DecalMapType mapType) const;
  64. RHI::Size GetImageDimensions(const DecalMapType mapType) const;
  65. RHI::Format GetFormat(const DecalMapType mapType) const;
  66. RHI::DeviceImageSubresourceLayout GetLayout(const DecalMapType mapType, int mip) const;
  67. AZStd::span<const uint8_t> GetRawImageData(const AZ::Name& mapName, int arrayLevel, int mip) const;
  68. bool AreAllAssetsReady() const;
  69. bool IsAssetReady(const MaterialData& materialData) const;
  70. bool AreAllTextureMapsPresent(const DecalMapType mapType) const;
  71. bool IsTextureMapPresentInMaterial(const MaterialData& materialData, const DecalMapType mapType) const;
  72. void ClearAssets();
  73. void ClearAsset(MaterialData& materialData);
  74. void QueueAssetLoads();
  75. void QueueAssetLoad(MaterialData& materialData);
  76. bool NeedsPacking() const;
  77. IndexableList<MaterialData> m_materials;
  78. AZStd::array<Data::Instance<RPI::StreamingImage>, DecalMapType_Num> m_textureArrayPacked;
  79. AZStd::unordered_set<AZ::Data::AssetId> m_assetsCurrentlyLoading;
  80. };
  81. } // namespace Render
  82. } // namespace AZ