[Fix] (BufferState, GL_Drawing): mark dirty buffers

This commit is contained in:
2025-05-08 21:40:48 +08:00
parent 5142f3c72b
commit 614c5f7324
3 changed files with 34 additions and 16 deletions
@@ -8,6 +8,9 @@
#include "../../../../Includes.h" #include "../../../../Includes.h"
namespace MG_GL::GL { namespace MG_GL::GL {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
void NormalizePixelFormat(GLenum internalFormat, GLenum type, GLenum format, GLenum* outInternalFormat, GLenum* outType, GLenum* outFormat) { void NormalizePixelFormat(GLenum internalFormat, GLenum type, GLenum format, GLenum* outInternalFormat, GLenum* outType, GLenum* outFormat) {
// if (format && *format == GL_BGRA) // if (format && *format == GL_BGRA)
// *format = GL_RGBA; // *format = GL_RGBA;
@@ -369,11 +372,11 @@ namespace MG_GL::GL {
return result; return result;
} }
static std::unordered_map<GLuint, GLuint> s_textureMap; static unordered_map<GLuint, GLuint> s_textureMap;
static std::unordered_map<GLuint, GLuint> s_vaoMap; static unordered_map<GLuint, GLuint> s_vaoMap;
static std::unordered_map<GLuint, GLuint> s_bufferMap; static unordered_map<GLuint, GLuint> s_bufferMap;
static std::unordered_map<GLuint, GLuint> s_programMap; static unordered_map<GLuint, GLuint> s_programMap;
static std::unordered_map<GLuint, GLuint> s_framebufferMap; static unordered_map<GLuint, GLuint> s_framebufferMap;
struct MipLevelInfo { struct MipLevelInfo {
GLenum internalFormat; GLenum internalFormat;
GLsizei width; GLsizei width;
@@ -389,7 +392,7 @@ namespace MG_GL::GL {
} }
#define CallAndCheck(operation) MG_Util::Debug::LogD("GLES call: %s", #operation); operation CheckGLESError(); #define CallAndCheck(operation) MG_Util::Debug::LogD("GLES call: %s", #operation); operation CheckGLESError();
static std::unordered_map<GLuint, std::unordered_map<GLint, bool>> s_textureLevelUploaded; // static std::unordered_map<GLuint, std::unordered_map<GLint, bool>> s_textureLevelUploaded;
void SyncAllTexturesToGLES(TextureState* textureState) { void SyncAllTexturesToGLES(TextureState* textureState) {
MG_Util::Debug::LogD("Syncing all textures to GLES..."); MG_Util::Debug::LogD("Syncing all textures to GLES...");
@@ -430,7 +433,7 @@ namespace MG_GL::GL {
mip.width, mip.height, 0, mip.width, mip.height, 0,
format, type, data 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)", MG_Util::Debug::LogD("Initial upload texture %u level %d (size=%zu)",
mgTexId, level, mip.pixelData.size()); mgTexId, level, mip.pixelData.size());
break; break;
@@ -452,6 +455,11 @@ namespace MG_GL::GL {
if (!obj.generated) if (!obj.generated)
continue; continue;
if (!obj.dirty)
continue;
obj.dirty = false;
// Gen real buffers at ES // Gen real buffers at ES
if (s_bufferMap.find(mgname) == s_bufferMap.end()) { if (s_bufferMap.find(mgname) == s_bufferMap.end()) {
GLuint glname; GLuint glname;
@@ -466,7 +474,7 @@ namespace MG_GL::GL {
CallAndCheck(::GLES::glBufferData( CallAndCheck(::GLES::glBufferData(
GL_ARRAY_BUFFER, GL_ARRAY_BUFFER,
obj.data.size(), obj.data.size(),
obj.data.data(), obj.dataValid ? obj.data.data() : nullptr,
obj.usage);) obj.usage);)
// s_bufferDirtyFlags_bufferObj[mgname] = obj.data.data(); // s_bufferDirtyFlags_bufferObj[mgname] = obj.data.data();
@@ -690,8 +698,8 @@ namespace MG_GL::GL {
CallAndCheck(::GLES::glBindVertexArray(glVAO);) CallAndCheck(::GLES::glBindVertexArray(glVAO);)
MG_Util::Debug::LogD("Bind VAO (MG -> ES): %d -> %d", mgid, glVAO); MG_Util::Debug::LogD("Bind VAO (MG -> ES): %d -> %d", mgid, glVAO);
std::string name = std::format("MG VAO {}", mgid); // std::string name = std::format("MG VAO {}", mgid);
::GLES::glObjectLabel(GL_VERTEX_ARRAY, mgid, name.length(), name.c_str()); // ::GLES::glObjectLabel(GL_VERTEX_ARRAY, mgid, name.length(), name.c_str());
if (vao.elementBuffer != 0 && s_bufferMap.find(vao.elementBuffer) != s_bufferMap.end()) { if (vao.elementBuffer != 0 && s_bufferMap.find(vao.elementBuffer) != s_bufferMap.end()) {
CallAndCheck(::GLES::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_bufferMap[vao.elementBuffer]);) CallAndCheck(::GLES::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s_bufferMap[vao.elementBuffer]);)
@@ -775,8 +783,8 @@ namespace MG_GL::GL {
GLuint glProgram = ::GLES::glCreateProgram(); GLuint glProgram = ::GLES::glCreateProgram();
ProgramObject& mgProgram = programState->programs_[currentProgram]; ProgramObject& mgProgram = programState->programs_[currentProgram];
std::string name = std::format("MG Program {}", currentProgram); // std::string name = std::format("MG Program {}", currentProgram);
::GLES::glObjectLabel(GL_PROGRAM, glProgram, name.length(), name.c_str()); // ::GLES::glObjectLabel(GL_PROGRAM, glProgram, name.length(), name.c_str());
// Attribute Names // Attribute Names
// before vertex shader attach // before vertex shader attach
+7 -2
View File
@@ -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); MG_Util::Debug::LogD("MG_State: Buffer: CommitStorage get buffer object %u at target 0x%x",it->second,target);
obj.usage = usage; obj.usage = usage;
obj.data.resize(size); 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); 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; return GL_NO_ERROR;
@@ -118,8 +122,8 @@ GLenum BufferState::AcquireBufferMemory(GLenum target, GLenum access, void** map
obj.isMapped = true; obj.isMapped = true;
*mappedPointer = obj.data.data(); *mappedPointer = obj.data.data();
obj.isMapped = true;
obj.accessMode = access; obj.accessMode = access;
obj.dirty = true;
return GL_NO_ERROR; return GL_NO_ERROR;
} }
@@ -138,6 +142,7 @@ GLenum BufferState::ReleaseBufferMemory(GLenum target) {
obj.isMapped = false; obj.isMapped = false;
obj.accessMode = GL_READ_WRITE; 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); MG_Util::Debug::LogD("MG_State: Buffer: ReleaseBufferMemory buffer at target 0x%x released mapped memory", target);
return GL_NO_ERROR; return GL_NO_ERROR;
} }
+7 -2
View File
@@ -9,10 +9,15 @@
#include "../../../Includes.h" #include "../../../Includes.h"
class BufferState { class BufferState {
template <typename K, typename V>
using unordered_map = ankerl::unordered_dense::map<K, V>;
public: public:
struct BufferObject { struct BufferObject {
GLenum usage = GL_STATIC_DRAW; GLenum usage = GL_STATIC_DRAW;
std::vector<GLubyte> data; std::vector<GLubyte> data;
bool dataValid = false;
bool dirty = false; // TODO: encapsulate this with an public API to RHI
bool isMapped = false; bool isMapped = false;
bool generated = false; bool generated = false;
GLenum accessMode = GL_READ_WRITE; GLenum accessMode = GL_READ_WRITE;
@@ -34,8 +39,8 @@ public:
void Delete(GLuint buffer); void Delete(GLuint buffer);
GLuint GetCurrentBinding(GLenum target) const; GLuint GetCurrentBinding(GLenum target) const;
std::unordered_map<GLenum, GLuint> currentBindings_; unordered_map<GLenum, GLuint> currentBindings_;
std::unordered_map<GLuint, BufferObject> buffers_; unordered_map<GLuint, BufferObject> buffers_;
private: private:
std::vector<GLuint> freeId_; std::vector<GLuint> freeId_;
GLuint lastId_ = 1; GLuint lastId_ = 1;