From 614c5f7324827ee384e8cfa12b6982f610801586 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Thu, 8 May 2025 21:40:48 +0800 Subject: [PATCH] [Fix] (BufferState, GL_Drawing): mark dirty buffers --- .../Implementations/GL/Drawing/GL_Drawing.cpp | 32 ++++++++++++------- MG/MG_GL/State/Buffer/BufferState.cpp | 9 ++++-- MG/MG_GL/State/Buffer/BufferState.h | 9 ++++-- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/MG/MG_GL/Implementations/GL/Drawing/GL_Drawing.cpp b/MG/MG_GL/Implementations/GL/Drawing/GL_Drawing.cpp index 484a0498..237df213 100644 --- a/MG/MG_GL/Implementations/GL/Drawing/GL_Drawing.cpp +++ b/MG/MG_GL/Implementations/GL/Drawing/GL_Drawing.cpp @@ -8,6 +8,9 @@ #include "../../../../Includes.h" namespace MG_GL::GL { + template + using unordered_map = ankerl::unordered_dense::map; + void NormalizePixelFormat(GLenum internalFormat, GLenum type, GLenum format, GLenum* outInternalFormat, GLenum* outType, GLenum* outFormat) { // if (format && *format == GL_BGRA) // *format = GL_RGBA; @@ -369,11 +372,11 @@ namespace MG_GL::GL { return result; } - static std::unordered_map s_textureMap; - static std::unordered_map s_vaoMap; - static std::unordered_map s_bufferMap; - static std::unordered_map s_programMap; - static std::unordered_map s_framebufferMap; + static unordered_map s_textureMap; + static unordered_map s_vaoMap; + static unordered_map s_bufferMap; + static unordered_map s_programMap; + static unordered_map s_framebufferMap; struct MipLevelInfo { GLenum internalFormat; GLsizei width; @@ -389,7 +392,7 @@ namespace MG_GL::GL { } #define CallAndCheck(operation) MG_Util::Debug::LogD("GLES call: %s", #operation); operation CheckGLESError(); - static std::unordered_map> s_textureLevelUploaded; +// static std::unordered_map> s_textureLevelUploaded; void SyncAllTexturesToGLES(TextureState* textureState) { MG_Util::Debug::LogD("Syncing all textures to GLES..."); @@ -430,7 +433,7 @@ namespace MG_GL::GL { mip.width, mip.height, 0, format, type, data );) - s_textureLevelUploaded[mgTexId][level] = true; +// s_textureLevelUploaded[mgTexId][level] = true; MG_Util::Debug::LogD("Initial upload texture %u level %d (size=%zu)", mgTexId, level, mip.pixelData.size()); break; @@ -452,6 +455,11 @@ namespace MG_GL::GL { if (!obj.generated) continue; + if (!obj.dirty) + continue; + + obj.dirty = false; + // Gen real buffers at ES if (s_bufferMap.find(mgname) == s_bufferMap.end()) { GLuint glname; @@ -466,7 +474,7 @@ namespace MG_GL::GL { CallAndCheck(::GLES::glBufferData( GL_ARRAY_BUFFER, obj.data.size(), - obj.data.data(), + obj.dataValid ? obj.data.data() : nullptr, obj.usage);) // s_bufferDirtyFlags_bufferObj[mgname] = obj.data.data(); @@ -690,8 +698,8 @@ namespace MG_GL::GL { CallAndCheck(::GLES::glBindVertexArray(glVAO);) MG_Util::Debug::LogD("Bind VAO (MG -> ES): %d -> %d", mgid, glVAO); - std::string name = std::format("MG VAO {}", mgid); - ::GLES::glObjectLabel(GL_VERTEX_ARRAY, mgid, name.length(), name.c_str()); +// std::string name = std::format("MG VAO {}", mgid); +// ::GLES::glObjectLabel(GL_VERTEX_ARRAY, mgid, name.length(), name.c_str()); if (vao.elementBuffer != 0 && s_bufferMap.find(vao.elementBuffer) != s_bufferMap.end()) { CallAndCheck(::GLES::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_bufferMap[vao.elementBuffer]);) @@ -775,8 +783,8 @@ namespace MG_GL::GL { GLuint glProgram = ::GLES::glCreateProgram(); ProgramObject& mgProgram = programState->programs_[currentProgram]; - std::string name = std::format("MG Program {}", currentProgram); - ::GLES::glObjectLabel(GL_PROGRAM, glProgram, name.length(), name.c_str()); +// std::string name = std::format("MG Program {}", currentProgram); +// ::GLES::glObjectLabel(GL_PROGRAM, glProgram, name.length(), name.c_str()); // Attribute Names // before vertex shader attach diff --git a/MG/MG_GL/State/Buffer/BufferState.cpp b/MG/MG_GL/State/Buffer/BufferState.cpp index 6b3a997b..1e70bfd8 100644 --- a/MG/MG_GL/State/Buffer/BufferState.cpp +++ b/MG/MG_GL/State/Buffer/BufferState.cpp @@ -96,7 +96,11 @@ GLenum BufferState::CommitStorage(GLenum target, GLsizeiptr size, const void* da MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target); obj.usage = usage; obj.data.resize(size); - if (data) memcpy(obj.data.data(), data, size); + if (data) { + memcpy(obj.data.data(), data, size); + obj.dataValid = true; + } + obj.dirty = true; MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage buffer at target 0x%x committed storage, size = %zu, usage=0x%x", target, size, usage); return GL_NO_ERROR; @@ -118,8 +122,8 @@ GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** map obj.isMapped = true; *mappedPointer = obj.data.data(); - obj.isMapped = true; obj.accessMode = access; + obj.dirty = true; return GL_NO_ERROR; } @@ -138,6 +142,7 @@ GLenum BufferState::ReleaseBufferMemory(GLenum target) { obj.isMapped = false; obj.accessMode = GL_READ_WRITE; + obj.dirty = true; MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory buffer at target 0x%x released mapped memory", target); return GL_NO_ERROR; } diff --git a/MG/MG_GL/State/Buffer/BufferState.h b/MG/MG_GL/State/Buffer/BufferState.h index 4e8c54ac..1ddd4462 100644 --- a/MG/MG_GL/State/Buffer/BufferState.h +++ b/MG/MG_GL/State/Buffer/BufferState.h @@ -9,10 +9,15 @@ #include "../../../Includes.h" class BufferState { + template + using unordered_map = ankerl::unordered_dense::map; + public: struct BufferObject { GLenum usage = GL_STATIC_DRAW; std::vector data; + bool dataValid = false; + bool dirty = false; // TODO: encapsulate this with an public API to RHI bool isMapped = false; bool generated = false; GLenum accessMode = GL_READ_WRITE; @@ -34,8 +39,8 @@ public: void Delete(GLuint buffer); GLuint GetCurrentBinding(GLenum target) const; - std::unordered_map currentBindings_; - std::unordered_map buffers_; + unordered_map currentBindings_; + unordered_map buffers_; private: std::vector freeId_; GLuint lastId_ = 1;