diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index 820f04e9..fb5e555f 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -156,7 +156,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } // namespace BufferImpl namespace VertexArrayImpl { - void SyncCurrentVAO(Bool needDivisor) { + void SyncCurrentVAO() { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif @@ -174,7 +174,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } else { backendVAOObject = backendVAOIt->second; } - backendVAOObject->SyncToBackend(currentVAOObject, needDivisor); + backendVAOObject->SyncToBackend(currentVAOObject); } } // namespace VertexArrayImpl @@ -388,7 +388,7 @@ namespace MobileGL::MG_Backend::DirectGLES { ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif BufferImpl::SyncNeccessaryBuffers(syncBit & DrawSyncBit::IndexBuffer, syncBit & DrawSyncBit::IndirectBuffer); - VertexArrayImpl::SyncCurrentVAO(syncBit & DrawSyncBit::Instancing); + VertexArrayImpl::SyncCurrentVAO(); TextureImpl::SyncNeccessaryTextures(); FramebufferImpl::SyncCurrentFBO(); PrgramImpl::SyncCurrentProgram(); @@ -856,8 +856,6 @@ namespace MobileGL::MG_Backend::DirectGLES { if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { MGLOG_E("ES glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE"); - - // Protector will automatically revert to previous fbo states return; } @@ -867,7 +865,6 @@ namespace MobileGL::MG_Backend::DirectGLES { errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); - // Protector will automatically revert to previous fbo states } } @@ -927,8 +924,6 @@ namespace MobileGL::MG_Backend::DirectGLES { }); if (MG_External::GLES::glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { MGLOG_E("ES glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE"); - - // Protector will automatically revert to previous fbo states return; } @@ -938,7 +933,6 @@ namespace MobileGL::MG_Backend::DirectGLES { errorLopper.Loop([file = __FILE__, line = __LINE__](auto err) { MGLOG_D("ES error (%s:%d): %s", file, line, MG_Util::ConvertGLEnumToString(err).c_str()); }); - // Protector will automatically revert to previous fbo states } } diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.cpp b/MobileGL/MG_Backend/DirectGLES/Managers.cpp index 04af6811..c9e5f8e8 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.cpp +++ b/MobileGL/MG_Backend/DirectGLES/Managers.cpp @@ -212,8 +212,38 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_External::GLES::glBindVertexArray(m_backendVAOId); } - void BackendVertexArrayObject::SyncToBackend(SharedPtr& stateVAOObject, - Bool needDivisor) { + void BackendVertexArrayObject::SyncAttributeBuffer(Uint index, + const MG_State::GLState::VertexAttribute& attrib) { + const auto& bufferObject = attrib.Buffer; + if (!bufferObject) { + MGLOG_W("Attribute has no bound buffer, skipping."); + return; + } + + const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObject); + if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) { + MGLOG_E("No backend buffer found for attribute's buffer, cannot bind attribute."); + return; + } + const auto& backendBufferObject = backendBufferIt->second; + + backendBufferObject->Bind(GL_ARRAY_BUFFER); + } + + void BackendVertexArrayObject::SyncAttributeFormat(Uint index, + const MG_State::GLState::VertexAttribute& attrib) { + if (attrib.Enabled) { + MGLOG_D("Binding attribute index %u for VAO ID: %u", index, m_backendVAOId); + MG_External::GLES::glEnableVertexAttribArray(index); + } else { + MGLOG_D("Disabling attribute index %u for VAO ID: %u", index, m_backendVAOId); + MG_External::GLES::glDisableVertexAttribArray(index); + } + + MG_External::GLES::glVertexAttribDivisor(index, attrib.Divisor); + } + + void BackendVertexArrayObject::SyncToBackend(SharedPtr& stateVAOObject) { #ifdef TRACY_ENABLE ZoneScopedC(TRACY_ZONECOLOR_BACKEND); #endif @@ -227,31 +257,24 @@ namespace MobileGL::MG_Backend::DirectGLES { Bind(); - for (const auto& attribIndex : stateVAOObject->GetDirtyAttributeIndices()) { - const auto& attrib = stateVAOObject->GetAttribute(attribIndex); - if (attrib.Enabled) { - MGLOG_D("Binding attribute index %u for VAO ID: %u", attribIndex, m_backendVAOId); - MG_External::GLES::glEnableVertexAttribArray(attribIndex); - } else { - MGLOG_D("Disabling attribute index %u for VAO ID: %u", attribIndex, m_backendVAOId); - MG_External::GLES::glDisableVertexAttribArray(attribIndex); - continue; + const auto& allAttributeVersions = stateVAOObject->GetAllAttributeVersions(); + const auto& allAttributes = stateVAOObject->GetAllAttributes(); + for (Uint attribIndex = 0; attribIndex < allAttributes.size(); ++attribIndex) { + Bool needsSyncFormat = allAttributeVersions[attribIndex].FormatVersion != + m_syncedAttributeVersions[attribIndex].FormatVersion; + Bool needsSyncBuffer = allAttributeVersions[attribIndex].BufferVersion != + m_syncedAttributeVersions[attribIndex].BufferVersion; + if (!needsSyncFormat && !needsSyncBuffer) continue; + + const auto& attrib = allAttributes[attribIndex]; + if (needsSyncBuffer) { + SyncAttributeBuffer(attribIndex, attrib); } - const auto& bufferObject = attrib.Buffer; - if (!bufferObject) { - MGLOG_W("Attribute has no bound buffer, skipping."); - continue; + if (needsSyncFormat) { + SyncAttributeFormat(attribIndex, attrib); } - const auto& backendBufferIt = BufferImpl::g_backendBufferObjects.find(bufferObject); - if (backendBufferIt == BufferImpl::g_backendBufferObjects.end()) { - MGLOG_E("No backend buffer found for attribute's buffer, cannot bind attribute."); - continue; - } - const auto& backendBufferObject = backendBufferIt->second; - - backendBufferObject->Bind(GL_ARRAY_BUFFER); if (!attrib.IsInteger) { MG_External::GLES::glVertexAttribPointer( attribIndex, attrib.Size, MG_Util::ConvertDataTypeToGLEnum(attrib.Type), @@ -261,10 +284,6 @@ namespace MobileGL::MG_Backend::DirectGLES { MG_Util::ConvertDataTypeToGLEnum(attrib.Type), attrib.Stride, (const void*)attrib.Offset); } - - if (needDivisor) { - MG_External::GLES::glVertexAttribDivisor(attribIndex, attrib.Divisor); - } } const auto& indexBufferBinding = stateVAOObject->GetIndexBufferBindingSlot().GetBoundObject(); @@ -278,7 +297,7 @@ namespace MobileGL::MG_Backend::DirectGLES { } } - stateVAOObject->ClearDirtyAttributes(); + m_syncedAttributeVersions = allAttributeVersions; } UnorderedMap, SharedPtr> diff --git a/MobileGL/MG_Backend/DirectGLES/Managers.h b/MobileGL/MG_Backend/DirectGLES/Managers.h index 196fd040..0a21aec8 100644 --- a/MobileGL/MG_Backend/DirectGLES/Managers.h +++ b/MobileGL/MG_Backend/DirectGLES/Managers.h @@ -44,13 +44,18 @@ namespace MobileGL::MG_Backend::DirectGLES { class BackendVertexArrayObject { public: BackendVertexArrayObject(); - void SyncToBackend(SharedPtr& stateVAOObject, Bool needDivisor); + void SyncToBackend(SharedPtr& stateVAOObject); Uint GetBackendVertexArrayId() { return m_backendVAOId; } void Bind(); private: + void SyncAttributeFormat(Uint index, const MG_State::GLState::VertexAttribute& attrib); + void SyncAttributeBuffer(Uint index, const MG_State::GLState::VertexAttribute& attrib); + Uint m_backendVAOId = 0; Bool m_isInitialized = false; + Array + m_syncedAttributeVersions; }; extern UnorderedMap, SharedPtr>