[Perf] (MG_Backend/DirectGLES): Add cache for Texture and Sampler binding.

This commit is contained in:
BZLZHH
2026-02-03 16:44:00 +08:00
parent b966ef8b5e
commit 5eff8b2e30
4 changed files with 71 additions and 25 deletions
+15 -23
View File
@@ -7,6 +7,7 @@
// End of Source File Header
#include "DirectGLES.h"
#include "MG_State/GLState/SamplerState/SamplerObject.h"
#include "Utils.h"
#include "Managers.h"
#include <MG_Util/Converters/GLToMG/TextureEnumConverter.h>
@@ -419,8 +420,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (Int unit = 0; unit < maxTextureUnits; ++unit) {
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit);
for (const auto& bindingSlot : textureUnit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject();
if (!textureObject) continue;
@@ -436,18 +435,18 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (backendTextureIt == TextureImpl::g_backendTextureObjects.end()) continue;
GLenum targetGL = MG_Util::ConvertTextureTargetToGLEnum(target);
backendTextureIt->second->Bind(targetGL);
backendTextureIt->second->Bind(targetGL, unit);
}
// Bind sampler object
// Bind sampler object if necessary
const auto& samplerObject = textureUnit.GetSamplerObject();
if (samplerObject) {
const auto& backendSamplerIt = SamplerImpl::g_backendSamplerObjects.find(samplerObject);
if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) {
backendSamplerIt->second->Bind(unit);
}
} else {
MG_External::GLES::glBindSampler(unit, 0);
}
}
}
@@ -551,7 +550,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
backendSamplerObject->SyncToBackend(samplerObject);
} else {
MG_External::GLES::glBindSampler(unit, 0);
SamplerImpl::UnbindSampler(unit);
}
}
}
@@ -751,14 +750,13 @@ namespace MobileGL::MG_Backend::DirectGLES {
});
}
bool UpdateTextureBindingAtTarget(GLenum target) {
Bool UpdateTextureBindingAtTarget(GLenum target) {
#ifdef TRACY_ENABLE
ZoneScopedNC(__func__, TRACY_ZONECOLOR_BACKEND);
#endif
auto unit = MG_State::pGLContext->GetActiveTextureUnit();
auto& textureUnit = MG_State::pGLContext->GetTextureUnitObject(unit);
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit);
auto textureTarget = MG_Util::ConvertGLEnumToTextureTarget(target);
if (!TextureImpl::IsSupportedTextureTarget(textureTarget)) {
MOBILEGL_ASSERT(false, " Texture target %s is not supported, skipping.",
@@ -782,7 +780,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
} else {
backendTextureObject = backendTextureIt->second;
}
backendTextureObject->Bind(target);
backendTextureObject->Bind(target, unit);
}
return true;
}
@@ -809,12 +807,6 @@ namespace MobileGL::MG_Backend::DirectGLES {
if (!UpdateTextureBindingAtTarget(target)) return;
// GLint realInternalFormat;
// MG_External::GLES::glGetTexLevelParameteriv(target, level, GL_TEXTURE_INTERNAL_FORMAT,
// &realInternalFormat); errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) {
// MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str());
// });
// internalformat = (GLenum)realInternalFormat;
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat);
GLenum format = GL_DEPTH_COMPONENT;
@@ -827,9 +819,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
MG_Util::ConvertGLEnumToString(format).c_str(), MG_Util::ConvertGLEnumToString(type).c_str());
TexturePixelDataType texturePixelDataType = MG_Util::ConvertGLEnumToTexturePixelDataType(type);
bool isDepthFormat =
Bool isDepthFormat =
MG_Util::IsDepthFormatInternalFormat(MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat));
bool isStencilFormat =
Bool isStencilFormat =
MG_Util::IsStencilFormatInternalFormat(MG_Util::ConvertGLEnumToTextureInternalFormat(internalformat));
if (!isDepthFormat) {
@@ -902,8 +894,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
});
auto mglInternalFormat = MG_Util::ConvertGLEnumToTextureInternalFormat(internalFormat);
bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(mglInternalFormat);
bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mglInternalFormat);
Bool isDepthFormat = MG_Util::IsDepthFormatInternalFormat(mglInternalFormat);
Bool isStencilFormat = MG_Util::IsStencilFormatInternalFormat(mglInternalFormat);
if (!isDepthFormat) {
MG_External::GLES::glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
@@ -946,7 +938,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto texture = slot.GetBoundObject();
auto backendTexture = TextureImpl::SyncTextureObjectToBackend(texture);
backendTexture->Bind(target);
backendTexture->Bind(target, unitIndex);
MG_External::GLES::glGenerateMipmap(target);
}
@@ -995,7 +987,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return;
}
bool found = false;
Bool found = false;
for (int i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; i++) {
if (backendFBO->GetCompactedAttachmentTypeAtDrawBufferIndex(i) == attachmentType) {
realDrawbuffer = i;
@@ -1048,7 +1040,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return;
}
bool found = false;
Bool found = false;
for (int i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; i++) {
if (backendFBO->GetCompactedAttachmentTypeAtDrawBufferIndex(i) == attachmentType) {
realDrawbuffer = i;
@@ -1102,7 +1094,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
return;
}
bool found = false;
Bool found = false;
for (int i = 0; i < MG_State::GLState::FramebufferObject::MAX_DRAW_BUFFERS; i++) {
if (backendFBO->GetCompactedAttachmentTypeAtDrawBufferIndex(i) == attachmentType) {
realDrawbuffer = i;
@@ -8,6 +8,8 @@
#pragma once
#include <Includes.h>
#include <MG_State/GLState/TextureState/TextureState.h>
#include <MG_State/GLState/SamplerState/SamplerObject.h>
#define CallAndCheck(operation) \
MGLOG_D("Call GLES func: %s", #operation); \
+42 -1
View File
@@ -7,6 +7,10 @@
// End of Source File Header
#include "Managers.h"
#include "MG_State/GLState/TextureState/TextureEnum.h"
#include "MG_State/GLState/TextureState/TextureObject.h"
#include "MG_State/GLState/TextureState/TextureState.h"
#include "MG_Util/Converters/GLToMG/TextureEnumConverter.h"
#include "Utils.h"
#include "DirectGLES.h"
@@ -345,11 +349,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
void BackendTextureObject::Bind(GLenum target) {
void BackendTextureObject::Bind(GLenum target, Uint unit) {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
auto targetN = static_cast<SizeT>(MG_Util::ConvertGLEnumToTextureTarget(target));
if (this == g_boundTexturesCache[unit][targetN]) return;
ActivateTextureUnit(unit);
MG_External::GLES::glBindTexture(target, m_backendTextureId);
g_boundTexturesCache[unit][targetN] = this;
}
Uint BackendTextureObject::GetBackendTextureId() {
@@ -759,6 +768,27 @@ namespace MobileGL::MG_Backend::DirectGLES {
}
}
void ActivateTextureUnit(Uint unit) {
if (unit == g_activeTextureUnit) {
return;
}
MG_External::GLES::glActiveTexture(GL_TEXTURE0 + unit);
g_activeTextureUnit = unit;
}
void UnbindTexture(Uint unit, GLenum target) { // Active unit will be modified
auto targetN = static_cast<SizeT>(MG_Util::ConvertGLEnumToTextureTarget(target));
if (g_boundTexturesCache[unit][targetN] == nullptr) return;
ActivateTextureUnit(unit);
MG_External::GLES::glBindTexture(target, 0);
g_boundTexturesCache[unit][targetN] = nullptr;
}
Uint g_activeTextureUnit = 0;
Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>,
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
g_boundTexturesCache;
UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>>
g_backendTextureObjects;
} // namespace TextureImpl
@@ -1194,7 +1224,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
#ifdef TRACY_ENABLE
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
#endif
if (g_boundSamplersCache[unit] == this) return;
MG_External::GLES::glBindSampler(static_cast<GLenum>(unit), m_backendSamplerId);
g_boundSamplersCache[unit] = this;
}
Uint BackendSamplerObject::GetBackendSamplerId() {
@@ -1204,6 +1237,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
return m_backendSamplerId;
}
void UnbindSampler(Uint unit) {
if (g_boundSamplersCache[unit] == nullptr) return;
MG_External::GLES::glBindSampler(static_cast<GLenum>(unit), 0);
g_boundSamplersCache[unit] = nullptr;
}
Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> g_boundSamplersCache;
UnorderedMap<SharedPtr<MG_State::GLState::SamplerObject>, SharedPtr<BackendSamplerObject>>
g_backendSamplerObjects;
} // namespace SamplerImpl
+12 -1
View File
@@ -90,13 +90,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
bool operator!=(const StateTextureBasicInfo& other) const { return !(*this == other); }
};
inline const Uint TempTextureUnit = 0;
class BackendTextureObject {
public:
BackendTextureObject();
void SyncMipmapsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncBuiltinSamplerToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void SyncTextureParamsToBackend(SharedPtr<MG_State::GLState::ITextureObject>& stateTextureObject);
void Bind(GLenum target);
void Bind(GLenum target, Uint unit = TempTextureUnit);
Uint GetBackendTextureId();
private:
@@ -112,8 +113,14 @@ namespace MobileGL::MG_Backend::DirectGLES {
Uint16 m_syncedTextureParamsVersion = 0;
};
void ActivateTextureUnit(Uint unit);
void UnbindTexture(Uint unit, GLenum target);
extern UnorderedMap<SharedPtr<MG_State::GLState::ITextureObject>, SharedPtr<BackendTextureObject>>
g_backendTextureObjects;
extern Array<Array<BackendTextureObject*, (SizeT)TextureTarget::TextureTargetCount>,
MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
g_boundTexturesCache;
extern Uint g_activeTextureUnit;
} // namespace TextureImpl
namespace FramebufferImpl {
@@ -193,6 +200,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
Uint16 m_syncedSamplerVersion = 0;
};
void UnbindSampler(Uint unit);
extern Array<BackendSamplerObject*, MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS>
g_boundSamplersCache;
extern UnorderedMap<SharedPtr<MG_State::GLState::SamplerObject>, SharedPtr<BackendSamplerObject>>
g_backendSamplerObjects;
} // namespace SamplerImpl