mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] implement renaming for buffer
This commit is contained in:
@@ -39,7 +39,14 @@ namespace MG_GL::GL {
|
|||||||
|
|
||||||
void BindBuffer(GLenum target, GLuint buffer) {
|
void BindBuffer(GLenum target, GLuint buffer) {
|
||||||
MG_Util::Debug::LogD("glBindBuffer, target: %d, buffer: %d", target, buffer);
|
MG_Util::Debug::LogD("glBindBuffer, target: %d, buffer: %d", target, buffer);
|
||||||
if (buffer != 0 && !MG_State::ValidateBufferHandle(buffer)) {
|
if (buffer != 0 &&
|
||||||
|
MG_State::ValidateGeneratedName(buffer) &&
|
||||||
|
!MG_State::ValidateAllocatedBufferHandle(buffer)) {
|
||||||
|
MG_Util::Debug::LogE("Actually creating buffer: %u", buffer);
|
||||||
|
GLenum result = MG_State::CreateBuffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer != 0 && !MG_State::ValidateAllocatedBufferHandle(buffer)) {
|
||||||
MG_State::SetError(GL_INVALID_VALUE);
|
MG_State::SetError(GL_INVALID_VALUE);
|
||||||
MG_Util::Debug::LogE("Invalid buffer handle: %u", buffer);
|
MG_Util::Debug::LogE("Invalid buffer handle: %u", buffer);
|
||||||
return;
|
return;
|
||||||
@@ -80,9 +87,9 @@ namespace MG_GL::GL {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum result = MG_State::CreateBuffers(n, buffers);
|
GLenum result = MG_State::GenBufferNames(n, buffers);
|
||||||
if (result == GL_NO_ERROR) {
|
if (result == GL_NO_ERROR) {
|
||||||
MG_Util::Debug::LogD("Generated buffers:");
|
MG_Util::Debug::LogD("Generated buffer names:");
|
||||||
for (GLsizei i = 0; i < n; ++i) {
|
for (GLsizei i = 0; i < n; ++i) {
|
||||||
MG_Util::Debug::LogD(" Buffer[%d] = %u", i, buffers[i]);
|
MG_Util::Debug::LogD(" Buffer[%d] = %u", i, buffers[i]);
|
||||||
}
|
}
|
||||||
@@ -100,7 +107,7 @@ namespace MG_GL::GL {
|
|||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValid = MG_State::ValidateBufferHandle(buffer);
|
bool isValid = MG_State::ValidateAllocatedBufferHandle(buffer);
|
||||||
// Should we report gl error here or in MG_State?
|
// Should we report gl error here or in MG_State?
|
||||||
MG_Util::Debug::LogD("Buffer %u is %s", buffer, isValid ? "valid" : "invalid");
|
MG_Util::Debug::LogD("Buffer %u is %s", buffer, isValid ? "valid" : "invalid");
|
||||||
return isValid ? GL_TRUE : GL_FALSE;
|
return isValid ? GL_TRUE : GL_FALSE;
|
||||||
|
|||||||
@@ -180,43 +180,138 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::unordered_map<GLuint, void*> s_bufferDirtyFlags_bufferObj;
|
// static std::unordered_map<GLuint, void*> s_bufferDirtyFlags_bufferObj;
|
||||||
void SyncAllBuffersToGLES(BufferState* bufferState) {
|
void SyncAllBuffersToGLES(BufferState* bufferState) {
|
||||||
GLint currentVBO = 0, currentEBO = 0;
|
GLint prev_vbo = 0;
|
||||||
CallAndCheck(::GLES::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, ¤tVBO);)
|
CallAndCheck(::GLES::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_vbo);)
|
||||||
CallAndCheck(::GLES::glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, ¤tEBO);)
|
|
||||||
for (auto& [mgBufferId, bufferObj] : bufferState->buffers_) {
|
|
||||||
if (!bufferObj.generated) continue;
|
|
||||||
|
|
||||||
// TODO: Check if the buffer changes rather than always update it.
|
for (auto& [mgname, obj] : bufferState->buffers_) {
|
||||||
if (s_bufferMap.find(mgBufferId) == s_bufferMap.end() || true) {
|
if (!obj.generated)
|
||||||
if (s_bufferMap.find(mgBufferId) == s_bufferMap.end()) {
|
continue;
|
||||||
GLuint glBuffer;
|
|
||||||
CallAndCheck(::GLES::glGenBuffers(1, &glBuffer);)
|
// Gen real buffers at ES
|
||||||
s_bufferMap[mgBufferId] = glBuffer;
|
if (s_bufferMap.find(mgname) == s_bufferMap.end()) {
|
||||||
}
|
GLuint glname;
|
||||||
CallAndCheck(::GLES::glBindBuffer(bufferObj.target, s_bufferMap[mgBufferId]);)
|
CallAndCheck(::GLES::glGenBuffers(1, &glname);)
|
||||||
CallAndCheck(::GLES::glBufferData(
|
s_bufferMap[mgname] = glname;
|
||||||
bufferObj.target,
|
|
||||||
bufferObj.data.size(),
|
|
||||||
bufferObj.data.data(),
|
|
||||||
bufferObj.usage
|
|
||||||
);)
|
|
||||||
s_bufferDirtyFlags_bufferObj[mgBufferId] = bufferObj.data.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint glname = s_bufferMap[mgname];
|
||||||
|
|
||||||
|
// Populate data to ES
|
||||||
|
CallAndCheck(::GLES::glBindBuffer(GL_ARRAY_BUFFER, glname);)
|
||||||
|
CallAndCheck(::GLES::glBufferData(
|
||||||
|
GL_ARRAY_BUFFER,
|
||||||
|
obj.data.size(),
|
||||||
|
obj.data.data(),
|
||||||
|
obj.usage);)
|
||||||
|
|
||||||
|
// s_bufferDirtyFlags_bufferObj[mgname] = obj.data.data();
|
||||||
}
|
}
|
||||||
CallAndCheck(::GLES::glBindBuffer(GL_ARRAY_BUFFER, currentVBO);)
|
CallAndCheck(::GLES::glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);)
|
||||||
CallAndCheck(::GLES::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, currentEBO);)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawArraysSHITTILY(GLenum mode, GLint first, GLsizei count) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static GLuint lastBoundVAO = 0;
|
static GLuint lastBoundVAO = 0;
|
||||||
static GLuint lastBoundProgram = 0;
|
static GLuint lastBoundProgram = 0;
|
||||||
static GLuint lastBoundFBO[2] = {0};
|
static GLuint lastBoundFBO[2] = {0};
|
||||||
static std::array<GLuint, 32> lastBoundTextures;
|
static std::array<GLuint, 32> lastBoundTextures;
|
||||||
|
|
||||||
|
void RealizeFBOState(GLenum fbtype) {
|
||||||
|
FramebufferState* fbState = MG_State_T::framebufferState;
|
||||||
|
|
||||||
|
GLuint fb = fbState->currentBindings_[fbtype];
|
||||||
|
if (fb != lastBoundFBO[(fbtype == GL_DRAW_FRAMEBUFFER) ? 0 : 1]) {
|
||||||
|
GLuint glFBO = 0;
|
||||||
|
|
||||||
|
if (fb == 0) {
|
||||||
|
CallAndCheck(::GLES::glBindFramebuffer(fbtype, 0);)
|
||||||
|
glFBO = 0;
|
||||||
|
} else {
|
||||||
|
bool isNewGlesFBO = false;
|
||||||
|
|
||||||
|
if (s_framebufferMap.find(fb) == s_framebufferMap.end()) {
|
||||||
|
CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
||||||
|
s_framebufferMap[fb] = glFBO;
|
||||||
|
CallAndCheck(::GLES::glBindFramebuffer(fbtype, glFBO);)
|
||||||
|
MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, fb);
|
||||||
|
isNewGlesFBO = true;
|
||||||
|
} else {
|
||||||
|
glFBO = s_framebufferMap[fb];
|
||||||
|
CallAndCheck(::GLES::glBindFramebuffer(fbtype, glFBO);)
|
||||||
|
MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, fb);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glFBO != 0) {
|
||||||
|
FramebufferObject* mgFBO = fbState->GetCurrentFBO(fbtype);
|
||||||
|
if (mgFBO) {
|
||||||
|
MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, fb);
|
||||||
|
|
||||||
|
for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
||||||
|
|
||||||
|
if (mgAtt.type != GL_TEXTURE_2D) {
|
||||||
|
MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, fb);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint expectedGLTexId = 0;
|
||||||
|
if (mgAtt.handle != 0) {
|
||||||
|
if (s_textureMap.count(mgAtt.handle)) {
|
||||||
|
expectedGLTexId = s_textureMap[mgAtt.handle];
|
||||||
|
} else {
|
||||||
|
MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, fb, mgAttachmentPoint);
|
||||||
|
for (auto const& [key, val] : s_textureMap)
|
||||||
|
MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint glesAttachedType = 0;
|
||||||
|
GLint glesAttachedName = 0;
|
||||||
|
|
||||||
|
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(fbtype, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
||||||
|
|
||||||
|
if (glesAttachedType == GL_TEXTURE) {
|
||||||
|
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(fbtype, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
||||||
|
} else if (glesAttachedType != GL_NONE) {
|
||||||
|
MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((GLuint)glesAttachedName != expectedGLTexId) {
|
||||||
|
MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
||||||
|
fb, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
||||||
|
|
||||||
|
CallAndCheck(::GLES::glFramebufferTexture2D(
|
||||||
|
fbtype,
|
||||||
|
mgAttachmentPoint,
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
expectedGLTexId,
|
||||||
|
mgAtt.mipLevel
|
||||||
|
);)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum status = ::GLES::glCheckFramebufferStatus(fbtype);
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
||||||
|
fb, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastBoundFBO[(fbtype == GL_DRAW_FRAMEBUFFER) ? 0 : 1] = fb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DrawArraysSHITTILY(GLenum mode, GLint first, GLsizei count) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void DrawElementsSHITTILY(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
|
void DrawElementsSHITTILY(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||||
CommonState* commonState = MG_State_T::commonState;
|
CommonState* commonState = MG_State_T::commonState;
|
||||||
TextureState* textureState = MG_State_T::textureState;
|
TextureState* textureState = MG_State_T::textureState;
|
||||||
@@ -578,95 +673,97 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Framebuffer
|
// Framebuffer
|
||||||
GLuint currentFBO = fbState->currentBindings_[GL_DRAW_FRAMEBUFFER];
|
RealizeFBOState(GL_DRAW_FRAMEBUFFER);
|
||||||
if (currentFBO != lastBoundFBO[0]) {
|
// GLuint currentFBO = fbState->currentBindings_[GL_DRAW_FRAMEBUFFER];
|
||||||
GLuint glFBO = 0;
|
// if (currentFBO != lastBoundFBO[0]) {
|
||||||
|
// GLuint glFBO = 0;
|
||||||
|
//
|
||||||
|
// if (currentFBO == 0) {
|
||||||
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0);)
|
||||||
|
// glFBO = 0;
|
||||||
|
// } else {
|
||||||
|
// bool isNewGlesFBO = false;
|
||||||
|
//
|
||||||
|
// if (s_framebufferMap.find(currentFBO) == s_framebufferMap.end()) {
|
||||||
|
// CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
||||||
|
// s_framebufferMap[currentFBO] = glFBO;
|
||||||
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
||||||
|
// MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
||||||
|
// GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
// if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
// MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after creation! Status: 0x%X (%s)",
|
||||||
|
// currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
||||||
|
// }
|
||||||
|
// isNewGlesFBO = true;
|
||||||
|
// } else {
|
||||||
|
// glFBO = s_framebufferMap[currentFBO];
|
||||||
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
||||||
|
// MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (glFBO != 0) {
|
||||||
|
// FramebufferObject* mgFBO = fbState->GetCurrentFBO(GL_DRAW_FRAMEBUFFER);
|
||||||
|
// if (mgFBO) {
|
||||||
|
// MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, currentFBO);
|
||||||
|
//
|
||||||
|
// for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
||||||
|
//
|
||||||
|
// if (mgAtt.type != GL_TEXTURE_2D) {
|
||||||
|
// MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, currentFBO);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// GLuint expectedGLTexId = 0;
|
||||||
|
// if (mgAtt.handle != 0) {
|
||||||
|
// if (s_textureMap.count(mgAtt.handle)) {
|
||||||
|
// expectedGLTexId = s_textureMap[mgAtt.handle];
|
||||||
|
// } else {
|
||||||
|
// MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, currentFBO, mgAttachmentPoint);
|
||||||
|
// for (auto const& [key, val] : s_textureMap)
|
||||||
|
// MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// GLint glesAttachedType = 0;
|
||||||
|
// GLint glesAttachedName = 0;
|
||||||
|
//
|
||||||
|
// CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
||||||
|
//
|
||||||
|
// if (glesAttachedType == GL_TEXTURE) {
|
||||||
|
// CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
||||||
|
// } else if (glesAttachedType != GL_NONE) {
|
||||||
|
// MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if ((GLuint)glesAttachedName != expectedGLTexId) {
|
||||||
|
// MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
||||||
|
// currentFBO, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
||||||
|
//
|
||||||
|
// CallAndCheck(::GLES::glFramebufferTexture2D(
|
||||||
|
// GL_FRAMEBUFFER,
|
||||||
|
// mgAttachmentPoint,
|
||||||
|
// GL_TEXTURE_2D,
|
||||||
|
// expectedGLTexId,
|
||||||
|
// mgAtt.mipLevel
|
||||||
|
// );)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
|
// if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
// MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
||||||
|
// currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// } else {
|
||||||
|
// MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", currentFBO);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lastBoundFBO[0] = currentFBO;
|
||||||
|
// }
|
||||||
|
|
||||||
if (currentFBO == 0) {
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0);)
|
|
||||||
glFBO = 0;
|
|
||||||
} else {
|
|
||||||
bool isNewGlesFBO = false;
|
|
||||||
|
|
||||||
if (s_framebufferMap.find(currentFBO) == s_framebufferMap.end()) {
|
|
||||||
CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
|
||||||
s_framebufferMap[currentFBO] = glFBO;
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
|
||||||
MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
|
||||||
GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after creation! Status: 0x%X (%s)",
|
|
||||||
currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
|
||||||
}
|
|
||||||
isNewGlesFBO = true;
|
|
||||||
} else {
|
|
||||||
glFBO = s_framebufferMap[currentFBO];
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
|
||||||
MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glFBO != 0) {
|
|
||||||
FramebufferObject* mgFBO = fbState->GetCurrentFBO(GL_DRAW_FRAMEBUFFER);
|
|
||||||
if (mgFBO) {
|
|
||||||
MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, currentFBO);
|
|
||||||
|
|
||||||
for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
|
||||||
|
|
||||||
if (mgAtt.type != GL_TEXTURE_2D) {
|
|
||||||
MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, currentFBO);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint expectedGLTexId = 0;
|
|
||||||
if (mgAtt.handle != 0) {
|
|
||||||
if (s_textureMap.count(mgAtt.handle)) {
|
|
||||||
expectedGLTexId = s_textureMap[mgAtt.handle];
|
|
||||||
} else {
|
|
||||||
MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, currentFBO, mgAttachmentPoint);
|
|
||||||
for (auto const& [key, val] : s_textureMap)
|
|
||||||
MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint glesAttachedType = 0;
|
|
||||||
GLint glesAttachedName = 0;
|
|
||||||
|
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
|
||||||
|
|
||||||
if (glesAttachedType == GL_TEXTURE) {
|
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
|
||||||
} else if (glesAttachedType != GL_NONE) {
|
|
||||||
MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((GLuint)glesAttachedName != expectedGLTexId) {
|
|
||||||
MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
|
||||||
currentFBO, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
|
||||||
|
|
||||||
CallAndCheck(::GLES::glFramebufferTexture2D(
|
|
||||||
GL_FRAMEBUFFER,
|
|
||||||
mgAttachmentPoint,
|
|
||||||
GL_TEXTURE_2D,
|
|
||||||
expectedGLTexId,
|
|
||||||
mgAtt.mipLevel
|
|
||||||
);)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
|
||||||
currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", currentFBO);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastBoundFBO[0] = currentFBO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (vao->elementBuffer != 0 || indices != nullptr) {
|
if (vao->elementBuffer != 0 || indices != nullptr) {
|
||||||
@@ -679,96 +776,6 @@ namespace MG_GL::GL {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealizeFBOState(GLenum fbtype) {
|
|
||||||
FramebufferState* fbState = MG_State_T::framebufferState;
|
|
||||||
|
|
||||||
GLuint fb = fbState->currentBindings_[fbtype];
|
|
||||||
if (fb != lastBoundFBO[(fbtype == GL_DRAW_FRAMEBUFFER) ? 0 : 1]) {
|
|
||||||
GLuint glFBO = 0;
|
|
||||||
|
|
||||||
if (fb == 0) {
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(fbtype, 0);)
|
|
||||||
glFBO = 0;
|
|
||||||
} else {
|
|
||||||
bool isNewGlesFBO = false;
|
|
||||||
|
|
||||||
if (s_framebufferMap.find(fb) == s_framebufferMap.end()) {
|
|
||||||
CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
|
||||||
s_framebufferMap[fb] = glFBO;
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(fbtype, glFBO);)
|
|
||||||
MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, fb);
|
|
||||||
isNewGlesFBO = true;
|
|
||||||
} else {
|
|
||||||
glFBO = s_framebufferMap[fb];
|
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(fbtype, glFBO);)
|
|
||||||
MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, fb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glFBO != 0) {
|
|
||||||
FramebufferObject* mgFBO = fbState->GetCurrentFBO(fbtype);
|
|
||||||
if (mgFBO) {
|
|
||||||
MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, fb);
|
|
||||||
|
|
||||||
for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
|
||||||
|
|
||||||
if (mgAtt.type != GL_TEXTURE_2D) {
|
|
||||||
MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, fb);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLuint expectedGLTexId = 0;
|
|
||||||
if (mgAtt.handle != 0) {
|
|
||||||
if (s_textureMap.count(mgAtt.handle)) {
|
|
||||||
expectedGLTexId = s_textureMap[mgAtt.handle];
|
|
||||||
} else {
|
|
||||||
MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, fb, mgAttachmentPoint);
|
|
||||||
for (auto const& [key, val] : s_textureMap)
|
|
||||||
MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint glesAttachedType = 0;
|
|
||||||
GLint glesAttachedName = 0;
|
|
||||||
|
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(fbtype, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
|
||||||
|
|
||||||
if (glesAttachedType == GL_TEXTURE) {
|
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(fbtype, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
|
||||||
} else if (glesAttachedType != GL_NONE) {
|
|
||||||
MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((GLuint)glesAttachedName != expectedGLTexId) {
|
|
||||||
MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
|
||||||
fb, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
|
||||||
|
|
||||||
CallAndCheck(::GLES::glFramebufferTexture2D(
|
|
||||||
fbtype,
|
|
||||||
mgAttachmentPoint,
|
|
||||||
GL_TEXTURE_2D,
|
|
||||||
expectedGLTexId,
|
|
||||||
mgAtt.mipLevel
|
|
||||||
);)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLenum status = ::GLES::glCheckFramebufferStatus(fbtype);
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
|
||||||
MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
|
||||||
fb, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", fb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastBoundFBO[(fbtype == GL_DRAW_FRAMEBUFFER) ? 0 : 1] = fb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlitFramebuffer(GLint srcX0,
|
void BlitFramebuffer(GLint srcX0,
|
||||||
GLint srcY0,
|
GLint srcY0,
|
||||||
GLint srcX1,
|
GLint srcX1,
|
||||||
@@ -801,92 +808,93 @@ namespace MG_GL::GL {
|
|||||||
CommonState* commonState = MG_State_T::commonState;
|
CommonState* commonState = MG_State_T::commonState;
|
||||||
FramebufferState* fbState = MG_State_T::framebufferState;
|
FramebufferState* fbState = MG_State_T::framebufferState;
|
||||||
|
|
||||||
GLuint currentFBO = fbState->currentBindings_[GL_DRAW_FRAMEBUFFER];
|
// GLuint currentFBO = fbState->currentBindings_[GL_DRAW_FRAMEBUFFER];
|
||||||
if (currentFBO != lastBoundFBO[0]) {
|
// if (currentFBO != lastBoundFBO[0]) {
|
||||||
GLuint glFBO = 0;
|
// GLuint glFBO = 0;
|
||||||
|
//
|
||||||
if (currentFBO == 0) {
|
// if (currentFBO == 0) {
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0);)
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, 0);)
|
||||||
glFBO = 0;
|
// glFBO = 0;
|
||||||
} else {
|
// } else {
|
||||||
bool isNewGlesFBO = false;
|
// bool isNewGlesFBO = false;
|
||||||
|
//
|
||||||
if (s_framebufferMap.find(currentFBO) == s_framebufferMap.end()) {
|
// if (s_framebufferMap.find(currentFBO) == s_framebufferMap.end()) {
|
||||||
CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
// CallAndCheck(::GLES::glGenFramebuffers(1, &glFBO);)
|
||||||
s_framebufferMap[currentFBO] = glFBO;
|
// s_framebufferMap[currentFBO] = glFBO;
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
||||||
MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
// MG_Util::Debug::LogD("Generated and bound new GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
||||||
isNewGlesFBO = true;
|
// isNewGlesFBO = true;
|
||||||
} else {
|
// } else {
|
||||||
glFBO = s_framebufferMap[currentFBO];
|
// glFBO = s_framebufferMap[currentFBO];
|
||||||
CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
// CallAndCheck(::GLES::glBindFramebuffer(GL_FRAMEBUFFER, glFBO);)
|
||||||
MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
// MG_Util::Debug::LogD("Bound existing GLES FBO %u for MobileGL FBO %u", glFBO, currentFBO);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (glFBO != 0) {
|
// if (glFBO != 0) {
|
||||||
FramebufferObject* mgFBO = fbState->GetCurrentFBO(GL_DRAW_FRAMEBUFFER);
|
// FramebufferObject* mgFBO = fbState->GetCurrentFBO(GL_DRAW_FRAMEBUFFER);
|
||||||
if (mgFBO) {
|
// if (mgFBO) {
|
||||||
MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, currentFBO);
|
// MG_Util::Debug::LogD("Checking/Syncing attachments for GLES FBO %u (MobileGL FBO %u)", glFBO, currentFBO);
|
||||||
|
//
|
||||||
for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
// for (auto const& [mgAttachmentPoint, mgAtt] : mgFBO->attachments) {
|
||||||
|
//
|
||||||
if (mgAtt.type != GL_TEXTURE_2D) {
|
// if (mgAtt.type != GL_TEXTURE_2D) {
|
||||||
MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, currentFBO);
|
// MG_Util::Debug::LogW("Skipping non-TEXTURE_2D attachment 0x%X for FBO %u", mgAttachmentPoint, currentFBO);
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
GLuint expectedGLTexId = 0;
|
// GLuint expectedGLTexId = 0;
|
||||||
if (mgAtt.handle != 0) {
|
// if (mgAtt.handle != 0) {
|
||||||
if (s_textureMap.count(mgAtt.handle)) {
|
// if (s_textureMap.count(mgAtt.handle)) {
|
||||||
expectedGLTexId = s_textureMap[mgAtt.handle];
|
// expectedGLTexId = s_textureMap[mgAtt.handle];
|
||||||
} else {
|
// } else {
|
||||||
MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, currentFBO, mgAttachmentPoint);
|
// MG_Util::Debug::LogE("MobileGL Texture %u for FBO %u attachment 0x%X not found in s_textureMap during FBO sync!", mgAtt.handle, currentFBO, mgAttachmentPoint);
|
||||||
for (auto const& [key, val] : s_textureMap)
|
// for (auto const& [key, val] : s_textureMap)
|
||||||
MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
// MG_Util::Debug::LogW(" key: %d, val: %d", key, val);
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
GLint glesAttachedType = 0;
|
// GLint glesAttachedType = 0;
|
||||||
GLint glesAttachedName = 0;
|
// GLint glesAttachedName = 0;
|
||||||
|
//
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
// CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &glesAttachedType);)
|
||||||
|
//
|
||||||
if (glesAttachedType == GL_TEXTURE) {
|
// if (glesAttachedType == GL_TEXTURE) {
|
||||||
CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
// CallAndCheck(::GLES::glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, mgAttachmentPoint, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &glesAttachedName);)
|
||||||
} else if (glesAttachedType != GL_NONE) {
|
// } else if (glesAttachedType != GL_NONE) {
|
||||||
MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
// MG_Util::Debug::LogW("GLES FBO %u attachment 0x%X has non-texture type 0x%X (expected GL_TEXTURE or GL_NONE)", glFBO, mgAttachmentPoint, glesAttachedType);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ((GLuint)glesAttachedName != expectedGLTexId) {
|
// if ((GLuint)glesAttachedName != expectedGLTexId) {
|
||||||
MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
// MG_Util::Debug::LogD("Syncing FBO %u attachment 0x%X: Expected GLES TexID %u, Found GLES ObjName %d. Attaching/Detaching...",
|
||||||
currentFBO, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
// currentFBO, mgAttachmentPoint, expectedGLTexId, glesAttachedName);
|
||||||
|
//
|
||||||
CallAndCheck(::GLES::glFramebufferTexture2D(
|
// CallAndCheck(::GLES::glFramebufferTexture2D(
|
||||||
GL_FRAMEBUFFER,
|
// GL_FRAMEBUFFER,
|
||||||
mgAttachmentPoint,
|
// mgAttachmentPoint,
|
||||||
GL_TEXTURE_2D,
|
// GL_TEXTURE_2D,
|
||||||
expectedGLTexId,
|
// expectedGLTexId,
|
||||||
mgAtt.mipLevel
|
// mgAtt.mipLevel
|
||||||
);)
|
// );)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
// GLenum status = ::GLES::glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
// if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
// MG_Util::Debug::LogE("Framebuffer %u (GLES FBO %u) is not complete after sync! Status: 0x%X (%s)",
|
||||||
currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
// currentFBO, glFBO, status, MG_Util::Debug::GLEnumToString(status));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
} else {
|
// } else {
|
||||||
MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", currentFBO);
|
// MG_Util::Debug::LogW("Could not get MobileGL FBO object for ID %u during attachment sync.", currentFBO);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
lastBoundFBO[0] = currentFBO;
|
// lastBoundFBO[0] = currentFBO;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
RealizeFBOState(GL_DRAW_FRAMEBUFFER);
|
||||||
|
|
||||||
static GLfloat lastClearColor[4] = {-1.0f, -1.0f, -1.0f, -1.0f};
|
static GLfloat lastClearColor[4] = {-1.0f, -1.0f, -1.0f, -1.0f};
|
||||||
if (memcmp(lastClearColor, commonState->clearColor, sizeof(lastClearColor)) != 0) {
|
if (memcmp(lastClearColor, commonState->clearColor, sizeof(lastClearColor)) != 0) {
|
||||||
|
|||||||
@@ -6,56 +6,79 @@
|
|||||||
|
|
||||||
#include "BufferState.h"
|
#include "BufferState.h"
|
||||||
|
|
||||||
GLenum BufferState::Create(GLuint* buffer) {
|
GLenum BufferState::GenName(GLuint *buffer) {
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Create called");
|
MG_Util::Debug::LogD("MG_State: Buffer: GenName");
|
||||||
if (!buffer) return GL_INVALID_VALUE;
|
if (!buffer)
|
||||||
|
return GL_INVALID_VALUE;
|
||||||
|
|
||||||
GLuint id = 0;
|
GLuint id = 0;
|
||||||
if (!freeIds_.empty()) {
|
if (freeId_.empty()) {
|
||||||
id = *freeIds_.begin();
|
id = lastId_++;
|
||||||
freeIds_.erase(freeIds_.begin());
|
|
||||||
} else {
|
} else {
|
||||||
id = ++lastId_;
|
id = freeId_.back();
|
||||||
|
freeId_.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
*buffer = id;
|
*buffer = id;
|
||||||
BufferObject& obj = buffers_[id];
|
MG_Util::Debug::LogD("MG_State: Buffer: Gen new name %d", id);
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", id);
|
|
||||||
|
return GL_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum BufferState::GenNameN(GLsizei n, GLuint* buffers) {
|
||||||
|
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN called with n=%d", n);
|
||||||
|
if (n < 0) return GL_INVALID_VALUE;
|
||||||
|
|
||||||
|
for (GLsizei i = 0; i < n; ++i) {
|
||||||
|
GLenum result = GenName(&buffers[i]);
|
||||||
|
if (result != GL_NO_ERROR) {
|
||||||
|
MG_Util::Debug::LogE("MG_State: Buffer: GenNameN failed with error 0x%x", result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MG_Util::Debug::LogD("MG_State: Buffer: GenNameN created buffers successfully");
|
||||||
|
return GL_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLenum BufferState::Create(GLuint buffer) {
|
||||||
|
MG_Util::Debug::LogD("MG_State: Buffer: Create called");
|
||||||
|
if (!buffer)
|
||||||
|
return GL_INVALID_VALUE;
|
||||||
|
|
||||||
|
if (ValidateAllocatedHandle(buffer))
|
||||||
|
return GL_INVALID_VALUE;
|
||||||
|
|
||||||
|
BufferObject& obj = buffers_[buffer];
|
||||||
|
MG_Util::Debug::LogD("MG_State: Buffer: Create created buffer %d", buffer);
|
||||||
obj.generated = true;
|
obj.generated = true;
|
||||||
|
|
||||||
return GL_NO_ERROR;
|
return GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum BufferState::CreateN(GLsizei n, GLuint* buffers) {
|
//GLenum BufferState::CreateN(GLsizei n, GLuint* buffers) {
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: CreateN called with n=%d", n);
|
// MG_Util::Debug::LogD("MG_State: Buffer: CreateN called with n=%d", n);
|
||||||
if (n < 0) return GL_INVALID_VALUE;
|
// if (n < 0) return GL_INVALID_VALUE;
|
||||||
|
//
|
||||||
for (GLsizei i = 0; i < n; ++i) {
|
// for (GLsizei i = 0; i < n; ++i) {
|
||||||
GLenum result = Create(&buffers[i]);
|
// GLenum result = Create(&buffers[i]);
|
||||||
if (result != GL_NO_ERROR) {
|
// if (result != GL_NO_ERROR) {
|
||||||
MG_Util::Debug::LogE("MG_State: Buffer: CreateN create buffer failed with error 0x%x", result);
|
// MG_Util::Debug::LogE("MG_State: Buffer: CreateN create buffer failed with error 0x%x", result);
|
||||||
return result;
|
// return result;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: CreateN created buffers successfully");
|
// MG_Util::Debug::LogD("MG_State: Buffer: CreateN created buffers successfully");
|
||||||
return GL_NO_ERROR;
|
// return GL_NO_ERROR;
|
||||||
}
|
//}
|
||||||
|
|
||||||
GLenum BufferState::Bind(GLenum target, GLuint buffer) {
|
GLenum BufferState::Bind(GLenum target, GLuint buffer) {
|
||||||
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
|
// We don't handle unallocated buffer names here, just plain bind
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Bind called with target=0x%x, buffer=%u", target, buffer);
|
|
||||||
|
|
||||||
if (buffer != 0) {
|
if (!IsValidTarget_(target)) return GL_INVALID_ENUM;
|
||||||
auto it = buffers_.find(buffer);
|
MG_Util::Debug::LogD("MG_State: Buffer: Bind called with target=%s, buffer=%u", MG_Util::Debug::GLEnumToString(target), buffer);
|
||||||
if (it == buffers_.end()) {
|
|
||||||
buffers_[buffer];
|
if (buffer != 0 && !ValidateAllocatedHandle(buffer)) {
|
||||||
} else {
|
MG_Util::Debug::LogE("MG_State: Buffer: Binding invalid buffer %d to %s", buffer, MG_Util::Debug::GLEnumToString(target));
|
||||||
BufferObject& obj = it->second;
|
return GL_INVALID_OPERATION;
|
||||||
if (obj.target != 0 && obj.target != target) {
|
|
||||||
MG_Util::Debug::LogE("MG_State: Buffer: Bind can not bind a buffer to different target 0x%x, current bind target is 0x%x", target, obj.target);
|
|
||||||
return GL_INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffers_[buffer].target = target;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
currentBindings_[target] = buffer;
|
currentBindings_[target] = buffer;
|
||||||
@@ -119,18 +142,25 @@ GLenum BufferState::ReleaseBufferMemory(GLenum target) {
|
|||||||
return GL_NO_ERROR;
|
return GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferState::ValidateHandle(GLuint buffer) {
|
bool BufferState::ValidateAllocatedHandle(GLuint buffer) {
|
||||||
bool isvalid = buffers_.count(buffer) > 0;
|
bool isValid = buffers_.find(buffer) != buffers_.end();
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: ValidateHandle called on buffer %u returns %d", buffer, isvalid);
|
MG_Util::Debug::LogD("MG_State: Buffer: ValidateAllocatedHandle called on buffer %u returns %d", buffer, isValid);
|
||||||
return isvalid;
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BufferState::ValidateGeneratedName(GLuint buffer) {
|
||||||
|
bool inFreeList = std::find(freeId_.begin(), freeId_.end(), buffer) != freeId_.end();
|
||||||
|
bool lessThanLast = buffer < lastId_; // lastId_ is not generated yet
|
||||||
|
MG_Util::Debug::LogD("MG_State: Buffer: ValidateAllocatedHandle called on buffer %u returns %d", buffer, lessThanLast && !inFreeList);
|
||||||
|
return lessThanLast && !inFreeList;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferState::Delete(GLuint buffer) {
|
void BufferState::Delete(GLuint buffer) {
|
||||||
if (buffers_.erase(buffer)) {
|
buffers_.erase(buffer);
|
||||||
freeIds_.insert(buffer);
|
if (ValidateGeneratedName(buffer))
|
||||||
for (auto& [target, id] : currentBindings_) {
|
freeId_.emplace_back(buffer);
|
||||||
if (id == buffer) id = 0;
|
for (auto& [target, id] : currentBindings_) {
|
||||||
}
|
if (id == buffer) id = 0;
|
||||||
}
|
}
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: Delete buffer %u", buffer);
|
MG_Util::Debug::LogD("MG_State: Buffer: Delete buffer %u", buffer);
|
||||||
}
|
}
|
||||||
@@ -179,7 +209,7 @@ GLenum BufferState::QueryPropertyIntVector(GLenum target, GLenum pname, GLint* p
|
|||||||
case GL_BUFFER_USAGE:
|
case GL_BUFFER_USAGE:
|
||||||
*params = static_cast<GLint>(buffer.usage);
|
*params = static_cast<GLint>(buffer.usage);
|
||||||
break;
|
break;
|
||||||
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector Query info about buffer %u succeed",buffer.target);
|
MG_Util::Debug::LogD("MG_State: Buffer: QueryPropertyIntVector Query info about buffer %u succeed", target);
|
||||||
default:
|
default:
|
||||||
return GL_INVALID_ENUM;
|
return GL_INVALID_ENUM;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
class BufferState {
|
class BufferState {
|
||||||
public:
|
public:
|
||||||
struct BufferObject {
|
struct BufferObject {
|
||||||
GLenum target = 0;
|
|
||||||
GLenum usage = GL_STATIC_DRAW;
|
GLenum usage = GL_STATIC_DRAW;
|
||||||
std::vector<GLubyte> data;
|
std::vector<GLubyte> data;
|
||||||
bool isMapped = false;
|
bool isMapped = false;
|
||||||
@@ -20,23 +19,26 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Return: the validity of the operation, according to OpenGL 3 standard
|
// Return: the validity of the operation, according to OpenGL 3 standard
|
||||||
GLenum Create(GLuint* buffer);
|
GLenum GenName(GLuint* buffer);
|
||||||
GLenum CreateN(GLsizei n, GLuint* buffers);
|
GLenum GenNameN(GLsizei n, GLuint* buffers);
|
||||||
|
GLenum Create(GLuint buffer);
|
||||||
|
// GLenum CreateN(GLsizei n, GLuint* buffers);
|
||||||
GLenum Bind(GLenum target, GLuint buffer);
|
GLenum Bind(GLenum target, GLuint buffer);
|
||||||
GLenum CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
GLenum CommitStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||||
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer);
|
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPointer);
|
||||||
GLenum ReleaseBufferMemory(GLenum target);
|
GLenum ReleaseBufferMemory(GLenum target);
|
||||||
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
|
GLenum QueryPropertyIntVector(GLenum target, GLenum pname, GLint* params) const;
|
||||||
|
|
||||||
bool ValidateHandle(GLuint buffer);
|
bool ValidateAllocatedHandle(GLuint buffer);
|
||||||
|
bool ValidateGeneratedName(GLuint buffer);
|
||||||
void Delete(GLuint buffer);
|
void Delete(GLuint buffer);
|
||||||
GLuint GetCurrentBinding(GLenum target) const;
|
GLuint GetCurrentBinding(GLenum target) const;
|
||||||
|
|
||||||
std::unordered_map<GLenum, GLuint> currentBindings_;
|
std::unordered_map<GLenum, GLuint> currentBindings_;
|
||||||
std::unordered_map<GLuint, BufferObject> buffers_;
|
std::unordered_map<GLuint, BufferObject> buffers_;
|
||||||
private:
|
private:
|
||||||
std::set<GLuint> freeIds_;
|
std::vector<GLuint> freeId_;
|
||||||
GLuint lastId_ = 0;
|
GLuint lastId_ = 1;
|
||||||
|
|
||||||
static bool IsValidTarget_(GLenum target);
|
static bool IsValidTarget_(GLenum target);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -160,12 +160,16 @@ namespace MG_State {
|
|||||||
return MG_State_T::bufferState->ReleaseBufferMemory(target);
|
return MG_State_T::bufferState->ReleaseBufferMemory(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum CreateBuffer(GLuint* buffer) {
|
GLenum CreateBuffer(GLuint buffer) {
|
||||||
return MG_State_T::bufferState->Create(buffer);
|
return MG_State_T::bufferState->Create(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum CreateBuffers(GLsizei n, GLuint* buffers) {
|
// GLenum CreateBuffers(GLsizei n, GLuint* buffers) {
|
||||||
return MG_State_T::bufferState->CreateN(n, buffers);
|
// return MG_State_T::bufferState->CreateN(n, buffers);
|
||||||
|
// }
|
||||||
|
|
||||||
|
GLenum GenBufferNames(GLsizei n, GLuint* buffers) {
|
||||||
|
return MG_State_T::bufferState->GenNameN(n, buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum BindBuffer(GLenum target, GLuint buffer) {
|
GLenum BindBuffer(GLenum target, GLuint buffer) {
|
||||||
@@ -181,8 +185,12 @@ namespace MG_State {
|
|||||||
return MG_State_T::bufferState->CommitStorage(target, size, data, usage);
|
return MG_State_T::bufferState->CommitStorage(target, size, data, usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ValidateBufferHandle(GLuint buffer) {
|
bool ValidateAllocatedBufferHandle(GLuint buffer) {
|
||||||
return MG_State_T::bufferState->ValidateHandle(buffer);
|
return MG_State_T::bufferState->ValidateAllocatedHandle(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ValidateGeneratedName(GLuint buffer) {
|
||||||
|
return MG_State_T::bufferState->ValidateGeneratedName(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteBuffer(GLuint buffer) {
|
void DeleteBuffer(GLuint buffer) {
|
||||||
|
|||||||
@@ -58,11 +58,13 @@ namespace MG_State {
|
|||||||
// Buffer
|
// Buffer
|
||||||
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr);
|
GLenum AcquireBufferMemory(GLenum target, GLenum access, void** mappedPtr);
|
||||||
GLenum ReleaseBufferMemory(GLenum target);
|
GLenum ReleaseBufferMemory(GLenum target);
|
||||||
GLenum CreateBuffer(GLuint* buffer);
|
GLenum CreateBuffer(GLuint buffer);
|
||||||
GLenum CreateBuffers(GLsizei n, GLuint* buffers);
|
// GLenum CreateBuffers(GLsizei n, GLuint* buffers);
|
||||||
|
GLenum GenBufferNames(GLsizei n, GLuint* buffers);
|
||||||
GLenum BindBuffer(GLenum target, GLuint buffer);
|
GLenum BindBuffer(GLenum target, GLuint buffer);
|
||||||
GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
GLenum CommitBufferStorage(GLenum target, GLsizeiptr size, const void* data, GLenum usage);
|
||||||
bool ValidateBufferHandle(GLuint buffer);
|
bool ValidateAllocatedBufferHandle(GLuint buffer);
|
||||||
|
bool ValidateGeneratedName(GLuint buffer);
|
||||||
void DeleteBuffer(GLuint buffer);
|
void DeleteBuffer(GLuint buffer);
|
||||||
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params);
|
GLenum QueryBufferPropertyIntVector(GLenum target, GLenum pname, GLint* params);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user