From b4be1292b8ce19051f7540a1f47f0dfb06e98a26 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 25 Feb 2026 11:04:28 +0800 Subject: [PATCH] [Feat] (MG_Backend/DirectVulkan): TextureManager mipmap completeness check --- .../Renderer/VkTextureManager.cpp | 65 ++++++++++++------- .../DirectVulkan/Renderer/VkTextureManager.h | 11 ++-- 2 files changed, 47 insertions(+), 29 deletions(-) diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp index 148f48ad..334e38e8 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.cpp @@ -68,10 +68,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { Bool VkTextureManager::SyncTexture(MG_State::GLState::ITextureObject &texture, TextureResource &outResource) { - TextureUploadTarget level0Target = TextureUploadTarget::Unknown; + TextureUploadTarget uploadTarget = TextureUploadTarget::Unknown; IntVec3 texelSize{0, 0, 0}; SizeT byteSize = 0; - if (!CheckLevel0Completeness(texture, level0Target, texelSize, byteSize)) { + Uint32 mipLevelCount = 0; + if (!CheckMipmapCompleteness(texture, uploadTarget, texelSize, byteSize, mipLevelCount)) { return false; } @@ -80,18 +81,13 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } - const Uint32 mipLevelCount = GetUploadMipLevelCount(*mipTexture, level0Target); - if (mipLevelCount == 0) { - return false; - } - - if (!SyncTextureResource(texture, level0Target, texelSize, byteSize, mipLevelCount, outResource)) { + if (!SyncTextureResource(texture, uploadTarget, texelSize, byteSize, mipLevelCount, outResource)) { return false; } Bool hasDirtyMipLevel = false; for (Uint32 level = 0; level < mipLevelCount; ++level) { - if (mipTexture->IsStorageDirty(level0Target, level)) { + if (mipTexture->IsStorageDirty(uploadTarget, level)) { hasDirtyMipLevel = true; break; } @@ -100,14 +96,14 @@ namespace MobileGL::MG_Backend::DirectVulkan { return true; } - if (!UploadDirtyMipLevels(*mipTexture, level0Target, outResource)) { + if (!UploadDirtyMipLevels(*mipTexture, uploadTarget, outResource)) { return false; } return true; } Bool VkTextureManager::SyncTextureResource(const MG_State::GLState::ITextureObject &texture, - TextureUploadTarget level0Target, + TextureUploadTarget uploadTarget, const IntVec3 &texelSize, SizeT byteSize, Uint32 mipLevels, TextureResource &resource) { const VkFormat format = GetVkFormat(texture.GetFormat()); @@ -120,7 +116,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (mipLevels == 0) { return false; } - if (level0Target != TextureUploadTarget::Texture2D) { + if (uploadTarget != TextureUploadTarget::Texture2D) { return false; } @@ -175,7 +171,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { } Bool VkTextureManager::UploadDirtyMipLevels(MG_State::GLState::TextureObjectMipmap &mipmapTexture, - TextureUploadTarget level0Target, + TextureUploadTarget uploadTarget, TextureResource &outResource) { struct UploadItem { Uint32 level = 0; @@ -190,18 +186,18 @@ namespace MobileGL::MG_Backend::DirectVulkan { VkDeviceSize stagingSize = 0; for (Uint32 level = 0; level < outResource.mipLevels; ++level) { - if (!mipmapTexture.IsStorageDirty(level0Target, level)) { + if (!mipmapTexture.IsStorageDirty(uploadTarget, level)) { continue; } - const auto texelSize = mipmapTexture.GetMipmapTexelSize(level0Target, level); - const auto byteSize = mipmapTexture.GetMipmapByteSize(level0Target, level); + const auto texelSize = mipmapTexture.GetMipmapTexelSize(uploadTarget, level); + const auto byteSize = mipmapTexture.GetMipmapByteSize(uploadTarget, level); if (texelSize.x() <= 0 || texelSize.y() <= 0 || byteSize == 0) { - mipmapTexture.MarkStorageDirty(level0Target, level, false); + mipmapTexture.MarkStorageDirty(uploadTarget, level, false); continue; } - const void* source = mipmapTexture.MapMipmapData(level0Target, level); + const void* source = mipmapTexture.MapMipmapData(uploadTarget, level); if (source == nullptr) { return false; } @@ -298,7 +294,7 @@ namespace MobileGL::MG_Backend::DirectVulkan { return false; } for (const auto& item : uploadItems) { - mipmapTexture.MarkStorageDirty(level0Target, item.level, false); + mipmapTexture.MarkStorageDirty(uploadTarget, item.level, false); } outResource.layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; return true; @@ -350,8 +346,11 @@ namespace MobileGL::MG_Backend::DirectVulkan { resource.format = VK_FORMAT_UNDEFINED; } - Bool VkTextureManager::CheckLevel0Completeness(const MG_State::GLState::ITextureObject& texture, TextureUploadTarget& outTarget, - IntVec3& outTexelSize, SizeT& outByteSize) { + Bool VkTextureManager::CheckMipmapCompleteness(const MG_State::GLState::ITextureObject& texture, + TextureUploadTarget& outTarget, + IntVec3& outTexelSize, + SizeT& outByteSize, + Uint32& outMipLevelCount) { const auto* mipTexture = dynamic_cast(&texture); if (!mipTexture) { return false; @@ -360,10 +359,26 @@ namespace MobileGL::MG_Backend::DirectVulkan { if (targets.empty()) { return false; } - outTarget = targets.front(); - outTexelSize = mipTexture->GetMipmapTexelSize(outTarget, 0); - outByteSize = mipTexture->GetMipmapByteSize(outTarget, 0); - return outTexelSize.x() > 0 && outTexelSize.y() > 0 && outByteSize > 0; + + for (const auto target : targets) { + const Uint32 mipLevelCount = GetUploadMipLevelCount(*mipTexture, target); + if (mipLevelCount == 0) { + continue; + } + + const auto level0TexelSize = mipTexture->GetMipmapTexelSize(target, 0); + const auto level0ByteSize = mipTexture->GetMipmapByteSize(target, 0); + if (level0TexelSize.x() <= 0 || level0TexelSize.y() <= 0 || level0ByteSize == 0) { + continue; + } + + outTarget = target; + outTexelSize = level0TexelSize; + outByteSize = level0ByteSize; + outMipLevelCount = mipLevelCount; + return true; + } + return false; } Uint32 VkTextureManager::GetUploadMipLevelCount(const MG_State::GLState::TextureObjectMipmap& texture, diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h index 09ae8ef0..a2330d22 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VkTextureManager.h @@ -48,16 +48,19 @@ private: Bool SyncTexture(MG_State::GLState::ITextureObject &texture, TextureResource &outResource); Bool SyncTextureResource(const MG_State::GLState::ITextureObject &texture, - TextureUploadTarget level0Target, + TextureUploadTarget uploadTarget, const IntVec3 &texelSize, SizeT byteSize, Uint32 mipLevels, TextureResource &resource); Bool UploadDirtyMipLevels(MG_State::GLState::TextureObjectMipmap &mipmapTexture, - TextureUploadTarget level0Target, + TextureUploadTarget uploadTarget, TextureResource &outResource); Bool ExecuteCmdBufImmediate(const std::function& recorder) const; void DestroyTextureResource(TextureResource& resource) const; - static Bool CheckLevel0Completeness(const MG_State::GLState::ITextureObject& texture, TextureUploadTarget& outTarget, - IntVec3& outTexelSize, SizeT& outByteSize); + static Bool CheckMipmapCompleteness(const MG_State::GLState::ITextureObject& texture, + TextureUploadTarget& outTarget, + IntVec3& outTexelSize, + SizeT& outByteSize, + Uint32& outMipLevelCount); static Uint32 GetUploadMipLevelCount(const MG_State::GLState::TextureObjectMipmap& texture, TextureUploadTarget target); static VkFormat GetVkFormat(TextureInternalFormat format);