From 7d5b4034ca3ac2c237de9da6554f2d75b66ee519 Mon Sep 17 00:00:00 2001 From: Anish Bhobe Date: Thu, 1 Aug 2024 23:44:13 +0200 Subject: [PATCH] Mipmap barrier fix. --- aster/image.cpp | 44 +++++++++++++++--------- aster/image.h | 16 +++++---- samples/00_util/gpu_resource_manager.cpp | 8 ++--- samples/03_model_render/asset_loader.cpp | 12 +++---- 4 files changed, 46 insertions(+), 34 deletions(-) diff --git a/aster/image.cpp b/aster/image.cpp index ff6ce9e..e890a8c 100644 --- a/aster/image.cpp +++ b/aster/image.cpp @@ -12,13 +12,13 @@ Image::Destroy(const Device *device) { if (!IsValid() || !IsOwned()) { - m_MipLevels_ = 0; + m_Flags_ = 0; return; } device->m_Device.destroy(m_View, nullptr); vmaDestroyImage(device->m_Allocator, m_Image, m_Allocation); - m_MipLevels_ = 0; + m_Flags_ = 0; } void @@ -28,8 +28,7 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF WARN_IF(!IsPowerOfTwo(extent.width) || !IsPowerOfTwo(extent.width), "Image {2} is {0}x{1} (Non Power of Two)", extent.width, extent.height, name ? name : ""); - const u32 mipLevels = isMipMapped ? 1 + Cast(floor(log2(eastl::max(extent.width, extent.height)))) : 1; - assert(mipLevels <= MIP_MASK); + const u8 mipLevels = isMipMapped ? 1 + Cast(floor(log2(eastl::max(extent.width, extent.height)))) : 1; auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst; if (isMipMapped) @@ -82,7 +81,9 @@ Texture::Init(const Device *device, const vk::Extent2D extent, vk::Format imageF m_View = view; m_Allocation = allocation; m_Extent = imageCreateInfo.extent; - m_MipLevels_ = mipLevels | OWNED_BIT | VALID_BIT; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 1; + m_MipLevels = mipLevels; device->SetName(m_Image, name); } @@ -110,8 +111,7 @@ TextureCube::Init(const Device *device, u32 cubeSide, vk::Format imageFormat, bo { WARN_IF(!IsPowerOfTwo(cubeSide), "Image {1} is {0}x{0} (Non Power of Two)", cubeSide, name ? name : ""); - const u32 mipLevels = isMipMapped ? 1 + Cast(floor(log2(cubeSide))) : 1; - assert(mipLevels <= MIP_MASK); + const u8 mipLevels = isMipMapped ? 1 + Cast(floor(log2(cubeSide))) : 1; auto usage = vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst; if (isMipMapped) @@ -167,7 +167,9 @@ TextureCube::Init(const Device *device, u32 cubeSide, vk::Format imageFormat, bo m_View = view; m_Allocation = allocation; m_Extent = extent; - m_MipLevels_ = mipLevels | OWNED_BIT | VALID_BIT; + m_MipLevels = mipLevels; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 6; device->SetName(m_Image, name); } @@ -220,7 +222,9 @@ AttachmentImage::Init(const Device *device, vk::Extent2D extent, vk::Format imag m_View = view; m_Allocation = allocation; m_Extent = imageCreateInfo.extent; - m_MipLevels_ = 1 | OWNED_BIT | VALID_BIT; + m_MipLevels = 1; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 1; device->SetName(m_Image, name); } @@ -274,7 +278,9 @@ DepthImage::Init(const Device *device, vk::Extent2D extent, cstr name) m_View = view; m_Allocation = allocation; m_Extent = imageCreateInfo.extent; - m_MipLevels_ = 1 | OWNED_BIT | VALID_BIT; + m_MipLevels = 1; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 1; device->SetName(m_Image, name); } @@ -340,13 +346,16 @@ StorageTexture::Init(const Device *device, vk::Extent2D extent, const vk::Format m_View = view; m_Allocation = allocation; m_Extent = imageCreateInfo.extent; - m_MipLevels_ = 1 | OWNED_BIT | VALID_BIT; + m_MipLevels = 1; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 1; device->SetName(m_Image, name); } void -StorageTextureCube::Init(const Device* device, u32 cubeSide, vk::Format imageFormat, bool isSampled, bool isMipMapped, cstr name) +StorageTextureCube::Init(const Device *device, u32 cubeSide, vk::Format imageFormat, bool isSampled, bool isMipMapped, + cstr name) { // Reasoning: // Transfer Src and Dst to copy to and from the buffer since Storage will often be loaded with info, and read for @@ -355,13 +364,12 @@ StorageTextureCube::Init(const Device* device, u32 cubeSide, vk::Format imageFor vk::ImageUsageFlagBits::eStorage | vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst; if (isSampled) { - WARN_IF(!IsPowerOfTwo(cubeSide), "Image {1} is {0}x{0} (Non Power of Two)", - cubeSide, name ? name : ""); + WARN_IF(!IsPowerOfTwo(cubeSide), "Image {1} is {0}x{0} (Non Power of Two)", cubeSide, + name ? name : ""); usage |= vk::ImageUsageFlagBits::eSampled; } - const u32 mipLevels = isMipMapped ? 1 + Cast(floor(log2(cubeSide))) : 1; - assert(mipLevels <= MIP_MASK); + const u8 mipLevels = isMipMapped ? 1 + Cast(floor(log2(cubeSide))) : 1; vk::ImageCreateInfo imageCreateInfo = { .flags = vk::ImageCreateFlagBits::eCubeCompatible, @@ -409,7 +417,9 @@ StorageTextureCube::Init(const Device* device, u32 cubeSide, vk::Format imageFor m_View = view; m_Allocation = allocation; m_Extent = imageCreateInfo.extent; - m_MipLevels_ = mipLevels | OWNED_BIT | VALID_BIT; + m_MipLevels = mipLevels; + m_Flags_ = OWNED_BIT | VALID_BIT; + m_LayerCount = 6; device->SetName(m_Image, name); } diff --git a/aster/image.h b/aster/image.h index ce6fcfa..592ba82 100644 --- a/aster/image.h +++ b/aster/image.h @@ -41,7 +41,10 @@ struct Image vk::Extent3D m_Extent; // Image.m_MipLevels_ is used for bookkeeping // If the image is Invalid, the remaining data in Image is used intrusively by `GpuResourceManager`. - u32 m_MipLevels_ = 0; + u8 m_EmptyPadding_ = 0; + u8 m_Flags_ = 0; + u8 m_LayerCount = 0; + u8 m_MipLevels = 0; [[nodiscard]] bool IsValid() const; [[nodiscard]] bool IsOwned() const; @@ -49,9 +52,8 @@ struct Image void Destroy(const Device *device); - constexpr static u32 VALID_BIT = 1u << 31; - constexpr static u32 OWNED_BIT = 1u << 30; - constexpr static u32 MIP_MASK = ~(VALID_BIT | OWNED_BIT); + constexpr static u8 VALID_BIT = 1u << 7; + constexpr static u8 OWNED_BIT = 1u << 6; }; struct Texture : Image @@ -101,17 +103,17 @@ static_assert(sizeof(StorageTextureCube) == sizeof(Image)); inline bool Image::IsValid() const { - return m_MipLevels_ & VALID_BIT; + return m_Flags_ & VALID_BIT; } inline bool Image::IsOwned() const { - return m_MipLevels_ & OWNED_BIT; + return m_Flags_ & OWNED_BIT; } inline u32 Image::GetMipLevels() const { - return m_MipLevels_ & MIP_MASK; + return m_MipLevels; } \ No newline at end of file diff --git a/samples/00_util/gpu_resource_manager.cpp b/samples/00_util/gpu_resource_manager.cpp index b8be54f..525fc0c 100644 --- a/samples/00_util/gpu_resource_manager.cpp +++ b/samples/00_util/gpu_resource_manager.cpp @@ -39,7 +39,7 @@ TextureManager::Commit(Texture *texture) *allocatedTexture = *texture; // Take ownership of the texture. - texture->m_MipLevels_ &= ~Texture::OWNED_BIT; + texture->m_Flags_ &= ~Texture::OWNED_BIT; return {index}; } @@ -53,7 +53,7 @@ TextureManager::Commit(Texture *texture) static_assert(std::is_trivially_copyable_v); *allocatedTexture = *texture; - texture->m_MipLevels_ &= ~Texture::OWNED_BIT; + texture->m_Flags_ &= ~Texture::OWNED_BIT; return {index}; } @@ -390,7 +390,7 @@ GpuResourceManager::Release(Texture *texture, TextureHandle handle) Texture *internal = m_TextureManager.Fetch(handle); *texture = *internal; - internal->m_MipLevels_ &= ~Texture::OWNED_BIT; + internal->m_Flags_ &= ~Texture::OWNED_BIT; Release(handle); } @@ -480,7 +480,7 @@ GpuResourceManager::Release(StorageTexture *texture, const StorageTextureHandle StorageTexture *internal = m_StorageTextureManager.Fetch(handle); *texture = *internal; - internal->m_MipLevels_ &= ~StorageTexture::OWNED_BIT; + internal->m_Flags_ &= ~StorageTexture::OWNED_BIT; Release(handle); } diff --git a/samples/03_model_render/asset_loader.cpp b/samples/03_model_render/asset_loader.cpp index 97d1547..2b4e5f7 100644 --- a/samples/03_model_render/asset_loader.cpp +++ b/samples/03_model_render/asset_loader.cpp @@ -218,7 +218,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, Texture *texture, vk::ImageLayo .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }, }; vk::ImageMemoryBarrier2 mipsStartBarrier = imageStartBarrier; @@ -230,7 +230,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, Texture *texture, vk::ImageLayo .baseMipLevel = 1, .levelCount = texture->GetMipLevels() - 1, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }; eastl::fixed_vector startBarriers = { mipsStartBarrier, @@ -261,7 +261,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, Texture *texture, vk::ImageLayo .baseMipLevel = 0, .levelCount = 1, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }, }; vk::DependencyInfo interMipDependency = { @@ -285,7 +285,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, Texture *texture, vk::ImageLayo .baseMipLevel = 0, .levelCount = texture->GetMipLevels(), .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }, }; vk::DependencyInfo imageReadyDependency = { @@ -298,13 +298,13 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, Texture *texture, vk::ImageLayo { .aspectMask = vk::ImageAspectFlagBits::eColor, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }, .dstSubresource = { .aspectMask = vk::ImageAspectFlagBits::eColor, .baseArrayLayer = 0, - .layerCount = 1, + .layerCount = texture->m_LayerCount, }, };