From 19e2a5dec232d1aaa738207ecfad87577eb4d5b6 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sat, 17 May 2025 00:19:40 +0800 Subject: [PATCH] [Feat] (BufferState): Implement BufferSubData. --- .../Implementations/GL/Buffer/GL_Buffer.cpp | 12 +++++++++++ .../Implementations/GL/Buffer/GL_Buffer.h | 1 + .../GLFuncsDefinitions/GLFuncsDefinitions.cpp | 2 +- MG/MG_GL/State/Buffer/BufferState.cpp | 21 +++++++++++++++++++ MG/MG_GL/State/Buffer/BufferState.h | 1 + MG/MG_GL/State/Core/GLState.cpp | 4 ++++ MG/MG_GL/State/Core/GLState.h | 1 + 7 files changed, 41 insertions(+), 1 deletion(-) diff --git a/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.cpp b/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.cpp index b2032f35..a878e6cc 100644 --- a/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.cpp +++ b/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.cpp @@ -163,6 +163,18 @@ namespace MG_GL::GL { return isValid ? GL_TRUE : GL_FALSE; } + void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + MG_Util::Debug::LogD("glBufferSubData, target: %s, offset: %lld, size: %lld, data: %p", + MG_Util::Debug::GLEnumToString(target), + static_cast(offset), + static_cast(size), + data); + GLenum result = MG_State::CommitBufferStorageRegion(target, offset, size, data); + if (result != GL_NO_ERROR) { + MG_State::SetError(result); + MG_Util::Debug::LogE("Error from MG State: %s", MG_Util::Debug::GLEnumToString(result)); + } + } void DeleteBuffers(GLsizei n, const GLuint *buffers) { MG_Util::Debug::LogD("glDeleteBuffers, n: %d, buffers: %p", n, buffers); diff --git a/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.h b/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.h index 156f2d3f..029d820d 100644 --- a/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.h +++ b/MG/MG_GL/Implementations/GL/Buffer/GL_Buffer.h @@ -15,6 +15,7 @@ namespace MG_GL::GL { GLboolean UnmapBuffer(GLenum target); void BindBuffer(GLenum target, GLuint buffer); void BufferData(GLenum target, GLsizeiptr size, const void* data, GLenum usage); + void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const void* data); void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params); void GenBuffers(GLsizei n, GLuint* buffers); void DeleteBuffers(GLsizei n, const GLuint *buffers); diff --git a/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp b/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp index a00683f9..f4a08b16 100644 --- a/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp +++ b/MG/MG_GL/Implementations/GL/GLFuncsDefinitions/GLFuncsDefinitions.cpp @@ -46,7 +46,7 @@ DECLARE_GL_FUNCTION_STUB_HEAD(void, BlendEquationSeparate, GLenum modeRGB, GLenu DECLARE_GL_FUNCTION_HEAD(void, BlendFunc, GLenum sfactor, GLenum dfactor) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFunc, sfactor,dfactor) DECLARE_GL_FUNCTION_HEAD(void, BlendFuncSeparate, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BlendFuncSeparate, sfactorRGB,dfactorRGB,sfactorAlpha,dfactorAlpha) DECLARE_GL_FUNCTION_HEAD(void, BufferData, GLenum target, GLsizeiptr size, const void *data, GLenum usage) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BufferData, target,size,data,usage) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BufferSubData, target,offset,size,data) +DECLARE_GL_FUNCTION_HEAD(void, BufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const void *data) DECLARE_GL_FUNCTION_END_NO_RETURN(void, BufferSubData, target,offset,size,data) DECLARE_GL_FUNCTION_HEAD(GLenum, CheckFramebufferStatus, GLenum target) DECLARE_GL_FUNCTION_END(GLenum, CheckFramebufferStatus, target) DECLARE_GL_FUNCTION_HEAD(void, Clear, GLbitfield mask) DECLARE_GL_FUNCTION_END_NO_RETURN(void, Clear, mask) DECLARE_GL_FUNCTION_HEAD(void, ClearColor, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) DECLARE_GL_FUNCTION_END_NO_RETURN(void, ClearColor, red,green,blue,alpha) diff --git a/MG/MG_GL/State/Buffer/BufferState.cpp b/MG/MG_GL/State/Buffer/BufferState.cpp index b85a7ad5..48e83cbf 100644 --- a/MG/MG_GL/State/Buffer/BufferState.cpp +++ b/MG/MG_GL/State/Buffer/BufferState.cpp @@ -85,6 +85,27 @@ GLenum BufferState::CommitStorage(GLenum target, GLsizeiptr size, const void* da return GL_NO_ERROR; } +GLenum BufferState::CommitStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData called on target 0x%x, offset=%ld, size=%ld", target, offset, size); + if (!IsValidTarget_(target)) return GL_INVALID_ENUM; + if (offset < 0 || size < 0) return GL_INVALID_VALUE; + + auto it = currentBindings_.find(target); + if (it == currentBindings_.end() || it->second == 0) + return GL_INVALID_OPERATION; + + BufferObject& obj = buffers_[it->second]; + MG_Util::Debug::LogD("MG_State: Buffer: BufferSubData get buffer object %u at target 0x%x", it->second, target); + + if (static_cast(offset + size) > obj.data.size()) return GL_INVALID_VALUE; + + if (data) { + memcpy(obj.data.data() + offset, data, size); + obj.dirty = true; + } + return GL_NO_ERROR; +} + GLenum BufferState::AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer) { MG_Util::Debug::LogD("MG_State: Buffer: AcquireBufferMemoryRange called with target=0x%x, offset=%ld, length=%ld, access=0x%x", target, offset, length, access); if (!IsValidTarget_(target)) { diff --git a/MG/MG_GL/State/Buffer/BufferState.h b/MG/MG_GL/State/Buffer/BufferState.h index f8dbf42b..1e49e6f8 100644 --- a/MG/MG_GL/State/Buffer/BufferState.h +++ b/MG/MG_GL/State/Buffer/BufferState.h @@ -32,6 +32,7 @@ public: GLenum Create(GLuint buffer); GLenum Bind(GLenum target, GLuint buffer); GLenum CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage); + GLenum CommitStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data); GLenum AcquireBufferMemoryRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void** mappedPointer); GLenum SyncBufferMemory(GLenum target, GLintptr offset, GLsizeiptr length); GLenum CopyBufferRange(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); diff --git a/MG/MG_GL/State/Core/GLState.cpp b/MG/MG_GL/State/Core/GLState.cpp index 123bed8d..c7a85f03 100644 --- a/MG/MG_GL/State/Core/GLState.cpp +++ b/MG/MG_GL/State/Core/GLState.cpp @@ -195,6 +195,10 @@ namespace MG_State { return MG_State_T::bufferState->CommitStorage(target, size, data, usage); } + GLenum CommitBufferStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + return MG_State_T::bufferState->CommitStorageRegion(target, offset, size, data); + } + bool ValidateAllocatedBufferHandle(GLuint buffer) { return MG_State_T::bufferState->ValidateAllocatedHandle(buffer); } diff --git a/MG/MG_GL/State/Core/GLState.h b/MG/MG_GL/State/Core/GLState.h index 7428be78..77451308 100644 --- a/MG/MG_GL/State/Core/GLState.h +++ b/MG/MG_GL/State/Core/GLState.h @@ -65,6 +65,7 @@ namespace MG_State { GLenum GenBufferNames(GLsizei n, GLuint* buffers); GLenum BindBuffer(GLenum target, GLuint buffer); GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage); + GLenum CommitBufferStorageRegion(GLenum target, GLintptr offset, GLsizeiptr size, const void* data); bool ValidateAllocatedBufferHandle(GLuint buffer); bool ValidateGeneratedName(GLuint buffer); void DeleteBuffer(GLuint buffer);