VkTexture.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. #pragma once
  6. #include <AnKi/Gr/Texture.h>
  7. #include <AnKi/Gr/Vulkan/VkGpuMemoryManager.h>
  8. #include <AnKi/Gr/BackendCommon/Functions.h>
  9. #include <AnKi/Util/HashMap.h>
  10. namespace anki {
  11. /// @addtogroup vulkan
  12. /// @{
  13. /// Texture container.
  14. class TextureImpl final : public Texture
  15. {
  16. friend class Texture;
  17. public:
  18. VkImage m_imageHandle = VK_NULL_HANDLE;
  19. GpuMemoryHandle m_memHandle;
  20. VkFormat m_vkFormat = VK_FORMAT_UNDEFINED;
  21. VkImageUsageFlags m_vkUsageFlags = 0;
  22. TextureImpl(CString name)
  23. : Texture(name)
  24. {
  25. }
  26. ~TextureImpl();
  27. Error init(const TextureInitInfo& init)
  28. {
  29. return initInternal(VK_NULL_HANDLE, init);
  30. }
  31. Error initExternal(VkImage image, const TextureInitInfo& init)
  32. {
  33. return initInternal(image, init);
  34. }
  35. Bool aspectValid(DepthStencilAspectBit aspect) const
  36. {
  37. return m_aspect == aspect || !!(aspect & m_aspect);
  38. }
  39. Bool usageValid(TextureUsageBit usage) const
  40. {
  41. #if ANKI_ASSERTIONS_ENABLED
  42. LockGuard<SpinLock> lock(m_usedForMtx);
  43. m_usedFor |= usage;
  44. #endif
  45. return (usage & m_usage) == usage;
  46. }
  47. /// By knowing the previous and new texture usage calculate the relavant info for a ppline barrier.
  48. VkImageMemoryBarrier computeBarrierInfo(TextureUsageBit before, TextureUsageBit after, const TextureSubresourceDesc& subresource,
  49. VkPipelineStageFlags& srcStages, VkPipelineStageFlags& dstStages) const;
  50. /// Predict the image layout.
  51. VkImageLayout computeLayout(TextureUsageBit usage) const;
  52. VkImageSubresourceRange computeVkImageSubresourceRange(const TextureSubresourceDesc& subresource) const
  53. {
  54. const TextureView in(this, subresource);
  55. VkImageSubresourceRange range = {};
  56. range.aspectMask = convertImageAspect(in.getDepthStencilAspect());
  57. range.baseMipLevel = in.getFirstMipmap();
  58. range.levelCount = in.getMipmapCount();
  59. const U32 faceCount = textureTypeIsCube(in.getTexture().getTextureType()) ? 6 : 1;
  60. range.baseArrayLayer = in.getFirstLayer() * faceCount + in.getFirstFace();
  61. range.layerCount = in.getLayerCount() * in.getFaceCount();
  62. return range;
  63. }
  64. VkImageView getImageView(const TextureSubresourceDesc& subresource) const
  65. {
  66. return getTextureViewEntry(subresource).m_handle;
  67. }
  68. private:
  69. class TextureViewEntry
  70. {
  71. public:
  72. VkImageView m_handle = VK_NULL_HANDLE;
  73. mutable U32 m_bindlessIndex = kMaxU32;
  74. mutable SpinLock m_bindlessIndexLock;
  75. };
  76. enum class ViewClass
  77. {
  78. kDefault,
  79. kDepth,
  80. kStencil,
  81. kCount,
  82. kFirst = 0
  83. };
  84. ANKI_ENUM_ALLOW_NUMERIC_OPERATIONS_FRIEND(ViewClass)
  85. Array<GrDynamicArray<TextureViewEntry>, U32(ViewClass::kCount)> m_textureViews;
  86. Array<TextureViewEntry, U32(ViewClass::kCount)> m_wholeTextureViews;
  87. #if ANKI_ASSERTIONS_ENABLED
  88. mutable TextureUsageBit m_usedFor = TextureUsageBit::kNone;
  89. mutable SpinLock m_usedForMtx;
  90. #endif
  91. [[nodiscard]] static VkImageCreateFlags calcCreateFlags(const TextureInitInfo& init);
  92. [[nodiscard]] Bool imageSupported(const TextureInitInfo& init);
  93. Error initImage(const TextureInitInfo& init);
  94. Error initViews();
  95. Error initInternal(VkImage externalImage, const TextureInitInfo& init);
  96. void computeBarrierInfo(TextureUsageBit usage, VkPipelineStageFlags& stages, VkAccessFlags& accesses) const;
  97. U32 translateSurfaceOrVolume(U32 layer, U32 face, U32 mip) const
  98. {
  99. const U32 faceCount = textureTypeIsCube(m_texType) ? 6 : 1;
  100. ANKI_ASSERT(layer < m_layerCount && face < faceCount && mip < m_mipCount);
  101. return layer * faceCount * m_mipCount + face * m_mipCount + mip;
  102. }
  103. const TextureViewEntry& getTextureViewEntry(const TextureSubresourceDesc& subresource) const;
  104. };
  105. /// @}
  106. } // end namespace anki