mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Perf] (MG_Backend/DirectGLES): Add cache for Texture and Sampler binding.
This commit is contained in:
@@ -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); \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user