mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-13 06:38:31 +09:00
[Optimize] (MG_Backend/DirectGLES): Texture object mipmap dirty bit
This commit is contained in:
@@ -205,8 +205,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// 1. textures bound to texture units (TODO: only sync ones that are used in current program)
|
||||
// 2. textures used in current FBO
|
||||
// 3. textures bound to image units (TODO)
|
||||
constexpr SizeT TextureTargetCount = static_cast<SizeT>(TextureTarget::TextureTargetCount);
|
||||
std::bitset<TextureTargetCount> dirtyTextureTargetBits;
|
||||
// constexpr SizeT TextureTargetCount = static_cast<SizeT>(TextureTarget::TextureTargetCount);
|
||||
// std::bitset<TextureTargetCount> dirtyTextureTargetBits;
|
||||
|
||||
Vector<SharedPtr<MG_State::GLState::ITextureObject>> texturesToSync;
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const auto& end = texturesToSync.end();
|
||||
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
|
||||
texturesToSync.push_back(textureObject);
|
||||
dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
|
||||
// dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,22 +234,22 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
const auto& end = texturesToSync.end();
|
||||
if (std::find(texturesToSync.begin(), end, textureObject) == end) {
|
||||
texturesToSync.push_back(textureObject);
|
||||
dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
|
||||
// dirtyTextureTargetBits.set(static_cast<SizeT>(textureObject->GetTarget()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
|
||||
BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
|
||||
|
||||
Vector<BackendTextureBindingProtector> textureBindingProtectors;
|
||||
for (SizeT target = 0; target < TextureTargetCount; ++target) {
|
||||
if (dirtyTextureTargetBits[target]) {
|
||||
textureBindingProtectors.emplace_back(
|
||||
MG_Util::ConvertTextureTargetToGLEnum(static_cast<TextureTarget>(target)));
|
||||
}
|
||||
}
|
||||
// BufferImpl::BackendBufferBindingProtector pixelUnpackProtector =
|
||||
// BufferImpl::BackendBufferBindingProtector(GL_PIXEL_UNPACK_BUFFER);
|
||||
//
|
||||
// Vector<BackendTextureBindingProtector> textureBindingProtectors;
|
||||
// for (SizeT target = 0; target < TextureTargetCount; ++target) {
|
||||
// if (dirtyTextureTargetBits[target]) {
|
||||
// textureBindingProtectors.emplace_back(
|
||||
// MG_Util::ConvertTextureTargetToGLEnum(static_cast<TextureTarget>(target)));
|
||||
// }
|
||||
// }
|
||||
|
||||
// Do real sync
|
||||
for (auto& textureObject : texturesToSync) {
|
||||
|
||||
@@ -366,6 +366,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
static_cast<SizeT>(baseSize.z()),
|
||||
0,
|
||||
0};
|
||||
|
||||
if (stateTextureObject->CheckDirtyBit(MG_State::GLState::TextureDirtyBit::StorageDirtyBit)) {
|
||||
switch (stateTextureObject->GetStorageType()) {
|
||||
case TextureStorageType::Mipmap: {
|
||||
auto* textureMipmapObject =
|
||||
@@ -487,6 +489,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
textureMipmapObject->ClearAllStorageDirtyBit();
|
||||
break;
|
||||
}
|
||||
case TextureStorageType::Buffer: {
|
||||
@@ -522,11 +526,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
&glType);
|
||||
|
||||
MG_External::GLES::glTexBuffer(GL_TEXTURE_BUFFER, glInternalFormat, backendId);
|
||||
|
||||
textureBufferObject->ClearAllStorageDirtyBit();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
THROW_UNIMPL_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
{ // Update built-in sampler parameters
|
||||
MGLOG_D("Updating sampler parameters for texture with ID: %u", m_backendTextureId);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
#include <Includes.h>
|
||||
#include "DirectGLES.h"
|
||||
#include "Utils.h"
|
||||
#include "MG_State/GLState/SamplerState/SamplerObject.h"
|
||||
#include "MG_State/GLState/TextureState/TextureEnum.h"
|
||||
#include <MG_State/GLState/TextureState/TextureObject.h>
|
||||
|
||||
@@ -788,6 +788,7 @@ namespace MobileGL {
|
||||
auto* texBufferObject = static_cast<MG_State::GLState::TextureObjectBuffer*>(textureObject.get());
|
||||
auto& bufferSlot = texBufferObject->GetBufferBindingSlot();
|
||||
bufferSlot.Bind(bufferObject);
|
||||
texBufferObject->SetStorageDirtyBit();
|
||||
|
||||
texBufferObject->SetInternalFormat(textureInternalFormat);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -278,6 +278,16 @@ namespace MobileGL {
|
||||
|
||||
Flags(typename Underlying::type b) : flags(b) {}
|
||||
|
||||
Flags Set(const Bit b) {
|
||||
flags |= static_cast<typename Underlying::type>(b);
|
||||
return flags;
|
||||
}
|
||||
|
||||
Flags Clear(const Bit b) {
|
||||
flags &= ~static_cast<typename Underlying::type>(b);
|
||||
return flags;
|
||||
}
|
||||
|
||||
// Flags - Bit
|
||||
Flags operator|(const Bit b) const { return Flags(flags | static_cast<typename Underlying::type>(b)); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user