[Optimize] (MG_Backend/DirectGLES): Texture object mipmap dirty bit

This commit is contained in:
2026-02-02 15:37:55 +08:00
parent cb2ce8f2a5
commit 8f55179493
11 changed files with 238 additions and 162 deletions
@@ -115,6 +115,13 @@ namespace MobileGL {
m_levelRange.y() = maxLevel;
}
bool TextureObjectBase::IsDirty() const {
return m_dirtyBit;
}
bool TextureObjectBase::CheckDirtyBit(TextureDirtyBit bit) const {
return m_dirtyBit & bit;
}
Uint TextureObjectWithOneMipmap::GetMipmapLevelCount() const {
return m_textureStorage.GetLevelCount();
}
@@ -146,6 +153,9 @@ namespace MobileGL {
void TextureObjectWithOneMipmap::MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel,
bool dirty) {
m_textureStorage.MarkDirty(GetIndexOfTextureUploadTarget(uploadTarget), mipmapLevel, dirty);
if (dirty) {
m_dirtyBit.Set(TextureDirtyBit::StorageDirtyBit);
}
}
bool TextureObjectWithOneMipmap::IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const {
@@ -189,6 +199,14 @@ namespace MobileGL {
return true;
}
void TextureObjectWithOneMipmap::ClearAllStorageDirtyBit() {
auto levelCount = GetMipmapLevelCount();
for (Uint i = 0; i < levelCount; ++i) {
m_textureStorage.MarkDirty(0, i, false);
}
m_dirtyBit.Clear(TextureDirtyBit::StorageDirtyBit);
}
// TODO: add other texture types as needed
} // namespace GLState
@@ -17,6 +17,12 @@
namespace MobileGL {
namespace MG_State {
namespace GLState {
enum class TextureDirtyBit: Uint8 {
None = 0,
StorageDirtyBit = 1 << 0, // refers to mipmap or TexBuffer according to tex type
ParamDirtyBit = 1 << 1
};
class ITextureObject {
public:
using TargetEnum = TextureTarget;
@@ -41,6 +47,8 @@ namespace MobileGL {
virtual const UintVec2& GetLevelRange() const = 0;
virtual void SetBaseLevel(Uint baseLevel) = 0;
virtual void SetMaxLevel(Uint maxLevel) = 0;
virtual bool IsDirty() const = 0;
virtual bool CheckDirtyBit(TextureDirtyBit bit) const = 0;
protected:
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
@@ -67,6 +75,9 @@ namespace MobileGL {
const UintVec2& GetLevelRange() const override;
void SetBaseLevel(Uint baseLevel) override;
void SetMaxLevel(Uint maxLevel) override;
bool IsDirty() const override;
bool CheckDirtyBit(TextureDirtyBit bit) const override;
virtual void ClearAllStorageDirtyBit() = 0;
protected:
const Uint m_externalIndex;
@@ -77,6 +88,8 @@ namespace MobileGL {
Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
UintVec2 m_levelRange = {0, 1000};
Flags<TextureDirtyBit> m_dirtyBit = TextureDirtyBit::None;
};
class TextureObjectMipmap : public TextureObjectBase {
@@ -92,7 +105,7 @@ namespace MobileGL {
virtual void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) = 0;
virtual void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) = 0;
virtual void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) = 0;
virtual void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty = true) = 0;
virtual bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
};
@@ -110,6 +123,7 @@ namespace MobileGL {
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) override;
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
void ClearAllStorageDirtyBit() override;
IntVec3 GetBaseSize() const override;
Bool IsComplete() const override;
@@ -42,6 +42,9 @@ namespace MobileGL {
void TextureObject2DCube::MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) {
m_textureStorage.MarkDirty(GetIndexOfTextureUploadTarget(uploadTarget), mipmapLevel, dirty);
if (dirty) {
m_dirtyBit.Set(TextureDirtyBit::StorageDirtyBit);
}
}
bool TextureObject2DCube::IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const {
@@ -82,6 +85,17 @@ namespace MobileGL {
// TODO: add more completeness checks based on texture type and mipmap levels
return true;
}
void TextureObject2DCube::ClearAllStorageDirtyBit() {
auto uploadTargetCount = GetUploadTargets().size();
auto levelCount = GetMipmapLevelCount();
for (SizeT target = 0; target < uploadTargetCount; ++target) {
for (Uint level = 0; level < levelCount; ++level) {
m_textureStorage.MarkDirty(target, level, false);
}
}
m_dirtyBit.Clear(TextureDirtyBit::StorageDirtyBit);
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -26,6 +26,7 @@ namespace MobileGL {
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, bool dirty) override;
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
void ClearAllStorageDirtyBit() override;
IntVec3 GetBaseSize() const override;
Bool IsComplete() const override;
@@ -23,6 +23,14 @@ namespace MobileGL {
MOBILEGL_ASSERT(target == TextureUploadTarget::TextureBuffer, "Invalid TextureUploadTarget!");
return m_bufferBindingSlot;
}
void TextureObjectBuffer::ClearAllStorageDirtyBit() {
m_dirtyBit.Clear(TextureDirtyBit::StorageDirtyBit);
}
void TextureObjectBuffer::SetStorageDirtyBit() {
m_dirtyBit.Set(TextureDirtyBit::StorageDirtyBit);
}
} // namespace GLState
} // namespace MG_State
} // namespace MobileGL
@@ -20,6 +20,8 @@ namespace MobileGL {
const Vector<TextureUploadTarget>& GetUploadTargets() const override { return m_uploadTargets; }
BindingSlot<BufferObject>& GetBufferBindingSlot(
TextureUploadTarget target = TextureUploadTarget::TextureBuffer);
void ClearAllStorageDirtyBit() override;
void SetStorageDirtyBit();
protected:
Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const override;