mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
179 lines
9.4 KiB
C++
179 lines
9.4 KiB
C++
// MobileGL - MobileGL/MG_State/GLState/TextureState/TextureObject.h
|
|
// Copyright (c) 2025-2026 MobileGL-Dev
|
|
// Licensed under the GNU Lesser General Public License v3.0:
|
|
// https://www.gnu.org/licenses/gpl-3.0.txt
|
|
// https://www.gnu.org/licenses/lgpl-3.0.txt
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
// End of Source File Header
|
|
|
|
#pragma once
|
|
#include "TextureEnum.h"
|
|
#include "MipmapUploadTargetArray.h"
|
|
#include "MG_Util/Types.h"
|
|
#include "../SamplerState/SamplerObject.h"
|
|
#include <Includes.h>
|
|
#include <MG_Util/Math/VectorTypes.h>
|
|
|
|
namespace MobileGL::MG_State::GLState {
|
|
class ITextureObject {
|
|
public:
|
|
using TargetEnum = TextureTarget;
|
|
virtual ~ITextureObject() = default;
|
|
|
|
virtual TextureStorageType GetStorageType() const = 0;
|
|
|
|
virtual TextureInternalFormat GetFormat() const = 0;
|
|
virtual TextureTarget GetTarget() const = 0;
|
|
virtual const Vector<TextureUploadTarget>& GetUploadTargets() const = 0;
|
|
virtual IntVec3 GetBaseSize() const = 0;
|
|
virtual const SharedPtr<SamplerObject>& GetSamplerObject() const = 0;
|
|
virtual void SetInternalFormat(TextureInternalFormat format) = 0;
|
|
virtual Bool IsComplete() const = 0;
|
|
virtual Uint GetExternalIndex() const = 0;
|
|
virtual const FloatVec4& GetBorderColor() const = 0;
|
|
virtual void SetBorderColor(const FloatVec4& color) = 0;
|
|
virtual const IntVec4& GetBorderColorI() const = 0;
|
|
virtual void SetBorderColorI(const IntVec4& color) = 0;
|
|
virtual const UintVec4& GetBorderColorUI() const = 0;
|
|
virtual void SetBorderColorUI(const UintVec4& color) = 0;
|
|
virtual TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const = 0;
|
|
virtual void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) = 0;
|
|
virtual void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) = 0;
|
|
virtual const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const = 0;
|
|
virtual const UintVec2& GetLevelRange() const = 0;
|
|
virtual void SetBaseLevel(Uint baseLevel) = 0;
|
|
virtual void SetMaxLevel(Uint maxLevel) = 0;
|
|
virtual Bool IsImmutable() const = 0;
|
|
virtual Uint GetImmutableLevels() const = 0;
|
|
virtual void SetImmutableLevels(Uint levels) = 0;
|
|
virtual Uint16 GetTextureParamsVersion() const = 0;
|
|
// Monotonic counter bumped on every CPU-side pixel mutation (see MarkStorageDirty).
|
|
// Backends compare it against a per-resource snapshot to skip re-syncing unchanged
|
|
// textures across draws (e.g. the block atlas bound across a whole terrain batch).
|
|
virtual Uint64 GetContentVersion() const = 0;
|
|
virtual Int GetSamples() const = 0;
|
|
virtual void SetSamples(Int samples) = 0;
|
|
virtual Bool HasFixedSampleLocations() const = 0;
|
|
virtual void SetFixedSampleLocations(Bool fixedSampleLocations) = 0;
|
|
virtual Uint64 GetLifetimeId() const = 0;
|
|
|
|
protected:
|
|
virtual Uint GetIndexOfTextureUploadTarget(TextureUploadTarget target) const = 0;
|
|
};
|
|
|
|
class TextureObjectBase : public ITextureObject {
|
|
public:
|
|
TextureObjectBase(TextureTarget target, Uint externalIndex);
|
|
virtual ~TextureObjectBase() = default;
|
|
|
|
TextureInternalFormat GetFormat() const override;
|
|
TextureTarget GetTarget() const override;
|
|
IntVec3 GetBaseSize() const override;
|
|
const SharedPtr<SamplerObject>& GetSamplerObject() const override;
|
|
void SetInternalFormat(TextureInternalFormat format) override;
|
|
Bool IsComplete() const override;
|
|
Uint GetExternalIndex() const override;
|
|
const FloatVec4& GetBorderColor() const override;
|
|
void SetBorderColor(const FloatVec4& color) override;
|
|
const IntVec4& GetBorderColorI() const override;
|
|
void SetBorderColorI(const IntVec4& color) override;
|
|
const UintVec4& GetBorderColorUI() const override;
|
|
void SetBorderColorUI(const UintVec4& color) override;
|
|
TextureSwizzleParam GetSwizzleParam(TextureSwizzleParam param) const override;
|
|
const Vec4<TextureSwizzleParam>& GetAllSwizzleParams() const override;
|
|
void SetSwizzleParam(TextureSwizzleParam param, TextureSwizzleParam value) override;
|
|
void SetSwizzleParamRGBA(const Vec4<TextureSwizzleParam>& values) override;
|
|
const UintVec2& GetLevelRange() const override;
|
|
void SetBaseLevel(Uint baseLevel) override;
|
|
void SetMaxLevel(Uint maxLevel) override;
|
|
Bool IsImmutable() const override;
|
|
Uint GetImmutableLevels() const override;
|
|
void SetImmutableLevels(Uint levels) override;
|
|
Uint16 GetTextureParamsVersion() const override;
|
|
Uint64 GetContentVersion() const override;
|
|
// Bumps the content version without touching per-level storage-dirty flags. Used when the
|
|
// set of defined mip levels grows via GPU-side mip generation (glGenerateMipmap): the level
|
|
// set changed (so a cached sampled view's level range is stale) but no CPU data is dirty.
|
|
void BumpContentVersion();
|
|
Int GetSamples() const override;
|
|
void SetSamples(Int samples) override;
|
|
Bool HasFixedSampleLocations() const override;
|
|
void SetFixedSampleLocations(Bool fixedSampleLocations) override;
|
|
Uint64 GetLifetimeId() const override;
|
|
|
|
protected:
|
|
static Uint64 AllocateLifetimeId();
|
|
|
|
const Uint m_externalIndex;
|
|
const Uint64 m_lifetimeId;
|
|
const TextureTarget m_target = TextureTarget::Unknown;
|
|
TextureInternalFormat m_internalFormat = TextureInternalFormat::Unknown;
|
|
SharedPtr<SamplerObject> m_sampler = nullptr;
|
|
FloatVec4 m_borderColor = {0.0f, 0.0f, 0.0f, 0.0f};
|
|
IntVec4 m_borderColorI = {0, 0, 0, 0};
|
|
UintVec4 m_borderColorUI = {0, 0, 0, 0};
|
|
Vec4<TextureSwizzleParam> m_swizzleParams = {TextureSwizzleParam::Red, TextureSwizzleParam::Green,
|
|
TextureSwizzleParam::Blue, TextureSwizzleParam::Alpha};
|
|
UintVec2 m_levelRange = {0, 1000};
|
|
Uint m_immutableLevels = 0;
|
|
Uint16 m_textureParamsVersion = 0;
|
|
// Starts at 1 so a freshly-created backend resource (snapshot 0) never spuriously
|
|
// matches before its first sync. Bumped only on dirty=true in MarkStorageDirty.
|
|
Uint64 m_contentVersion = 1;
|
|
Int m_samples = 0;
|
|
Bool m_fixedSampleLocations = true;
|
|
};
|
|
|
|
class TextureObjectMipmap : public TextureObjectBase {
|
|
public:
|
|
TextureObjectMipmap(TextureTarget target, Uint externalIndex) : TextureObjectBase(target, externalIndex) {}
|
|
|
|
TextureStorageType GetStorageType() const override { return TextureStorageType::Mipmap; }
|
|
|
|
virtual Uint GetMipmapLevelCount() const = 0;
|
|
virtual const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
|
|
virtual const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const = 0;
|
|
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 = true) = 0;
|
|
virtual Bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const = 0;
|
|
};
|
|
|
|
// Cheap replacement for dynamic_cast on the hot path: TextureObjectMipmap is the
|
|
// only hierarchy branch whose storage type reports Mipmap, so the tag check makes
|
|
// the static_cast safe.
|
|
inline TextureObjectMipmap* AsMipmapTexture(ITextureObject* texture) {
|
|
return (texture && texture->GetStorageType() == TextureStorageType::Mipmap)
|
|
? static_cast<TextureObjectMipmap*>(texture)
|
|
: nullptr;
|
|
}
|
|
inline const TextureObjectMipmap* AsMipmapTexture(const ITextureObject* texture) {
|
|
return (texture && texture->GetStorageType() == TextureStorageType::Mipmap)
|
|
? static_cast<const TextureObjectMipmap*>(texture)
|
|
: nullptr;
|
|
}
|
|
|
|
class TextureObjectWithOneMipmap : public TextureObjectMipmap {
|
|
public:
|
|
TextureObjectWithOneMipmap(TextureTarget target, Uint externalIndex)
|
|
: TextureObjectMipmap(target, externalIndex) {}
|
|
virtual ~TextureObjectWithOneMipmap() = default;
|
|
|
|
Uint GetMipmapLevelCount() const override;
|
|
const IntVec3 GetMipmapTexelSize(TextureUploadTarget target, Uint mipmapLevel) const override;
|
|
const SizeT GetMipmapByteSize(TextureUploadTarget target, Uint mipmapLevel) const override;
|
|
void AllocateStorage(TextureUploadTarget uploadTarget, Uint mipmapLevel, MipmapInput input) override;
|
|
void UpdateMipmapSubData(TextureUploadTarget uploadTarget, Uint mipmapLevel, DataPtr input) override;
|
|
void* MapMipmapData(TextureUploadTarget uploadTarget, Uint mipmapLevel) override;
|
|
void MarkStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel, Bool dirty) override;
|
|
bool IsStorageDirty(TextureUploadTarget uploadTarget, Uint mipmapLevel) const override;
|
|
|
|
IntVec3 GetBaseSize() const override;
|
|
Bool IsComplete() const override;
|
|
|
|
protected:
|
|
MipmapUploadTargetArray<1> m_textureStorage;
|
|
};
|
|
} // namespace MobileGL::MG_State::GLState
|