diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index fb5e555f..bb90bdc4 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -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 @@ -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; diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h index f57f56ab..f6ad4149 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.h +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.h @@ -8,6 +8,8 @@ #pragma once #include +#include +#include #define CallAndCheck(operation) \ MGLOG_D("Call GLES func: %s", #operation); \ diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 07e3bb86..e71d2342 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -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(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(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, + MG_State::GLState::TextureState::MAX_TEXTURE_IMAGE_UNITS> + g_boundTexturesCache; UnorderedMap, SharedPtr> 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(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(unit), 0); + g_boundSamplersCache[unit] = nullptr; + } + + Array g_boundSamplersCache; UnorderedMap, SharedPtr> g_backendSamplerObjects; } // namespace SamplerImpl diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index bb7b25d3..709f6f49 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -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& stateTextureObject); void SyncBuiltinSamplerToBackend(SharedPtr& stateTextureObject); void SyncTextureParamsToBackend(SharedPtr& 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> g_backendTextureObjects; + extern Array, + 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 + g_boundSamplersCache; extern UnorderedMap, SharedPtr> g_backendSamplerObjects; } // namespace SamplerImpl