diff --git a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp index 79a8c756..4cd36a68 100644 --- a/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp +++ b/MobileGL/MG_Backend/DirectVulkan/Renderer/VulkanRenderer.cpp @@ -3293,7 +3293,10 @@ void main() { } auto vtxUploadOk = UploadAndBindVertexBuffers(frame.commandBuffer, vao, drawParams); - MOBILEGL_ASSERT(vtxUploadOk, "SetupDraw skipped: failed to upload vertex buffers"); + if (!vtxUploadOk) { + MGLOG_E("SetupDraw skipped: failed to upload vertex buffers"); + return false; + } if (aspects & DrawSetupAspect::IndexBuffer) { auto idxUploadOk = UploadAndBindIndexBuffer(frame, vao, pIndexBufferView); diff --git a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp index 90dc3ae8..c1dc9849 100644 --- a/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp +++ b/MobileGL/MG_Impl/GLImpl/Buffer/GL_Buffer.cpp @@ -1275,6 +1275,8 @@ namespace MobileGL::MG_Impl::GLImpl { return; } + if (!BufferImpl::ValidateBufferName(buffer, true)) return; + Bool doesBufferObjectCreated = MG_State::pGLContext->ValidateBufferObject(buffer); if (!doesBufferObjectCreated) { MG_State::pGLContext->CreateBufferObject(buffer); @@ -1304,6 +1306,8 @@ namespace MobileGL::MG_Impl::GLImpl { return; } + if (!BufferImpl::ValidateBufferName(buffer, true)) return; + Bool doesBufferObjectCreated = MG_State::pGLContext->ValidateBufferObject(buffer); if (!doesBufferObjectCreated) { MG_State::pGLContext->CreateBufferObject(buffer); diff --git a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp index a4b7a77f..bf4bc47a 100644 --- a/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp +++ b/MobileGL/MG_Impl/GLImpl/Drawing/GL_Drawing.cpp @@ -9,6 +9,7 @@ #include "GL_Drawing.h" #include #include +#include #include namespace MobileGL::MG_Impl::GLImpl { @@ -65,6 +66,15 @@ namespace MobileGL::MG_Impl::GLImpl { return false; } + const auto& vao = MG_State::pGLContext->GetBoundVertexArray(); + if (MG_State::pEGLContext->IsCurrentContextOpenGLCoreProfile() && vao && vao->GetExternalIndex() == 0) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeUnique("MG_Impl/GLImpl", functionName, + "Default vertex array object cannot be used for drawing in core profile.")); + return false; + } + return true; } diff --git a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp index 912fed75..56495634 100644 --- a/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp +++ b/MobileGL/MG_Impl/GLImpl/Exporting/Definitions.cpp @@ -18,6 +18,7 @@ #include "../Framebuffer/GL_Framebuffer.h" #include "../VertexArray/GL_VertexArray.h" #include "../Sync/GL_Sync.h" +#include #define DECLARE_GL_FUNCTION_STUB_HEAD(type, name, ...) MOBILEGL_GL_API type gl##name(__VA_ARGS__) { @@ -211,7 +212,15 @@ DECLARE_GL_FUNCTION_HEAD(void, CompressedTexSubImage3D, GLenum target, GLint lev DECLARE_GL_FUNCTION_STUB_HEAD(void, GenQueries, GLsizei n, GLuint* ids) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GenQueries, n, ids) DECLARE_GL_FUNCTION_STUB_HEAD(void, DeleteQueries, GLsizei n, const GLuint* ids) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, DeleteQueries, n, ids) DECLARE_GL_FUNCTION_STUB_HEAD(GLboolean, IsQuery, GLuint id) DECLARE_GL_FUNCTION_STUB_END(GLboolean, IsQuery, id) -DECLARE_GL_FUNCTION_STUB_HEAD(void, BeginQuery, GLenum target, GLuint id) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, BeginQuery, target, id) +MOBILEGL_GL_API void glBeginQuery(GLenum target, GLuint id) { + MGLOG_W("Stub function: %s(...)", __FUNCTION__); + if (id != 0) { + MobileGL::MG_State::pGLContext->RecordError( + MobileGL::ErrorCode::InvalidOperation, + MobileGL::MakeUnique("MG_Impl/GLImpl", __FUNCTION__, + "Query object does not exist.")); + } +} DECLARE_GL_FUNCTION_STUB_HEAD(void, EndQuery, GLenum target) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, EndQuery, target) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryiv, GLenum target, GLenum pname, GLint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryiv, target, pname, params) DECLARE_GL_FUNCTION_STUB_HEAD(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint* params) DECLARE_GL_FUNCTION_STUB_END_NO_RETURN(void, GetQueryObjectuiv, id, pname, params) diff --git a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp index 11894874..3e39021e 100644 --- a/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp +++ b/MobileGL/MG_Impl/GLImpl/Texture/GL_Texture.cpp @@ -2112,6 +2112,13 @@ namespace MobileGL::MG_Impl::GLImpl { return; } + if (!MG_State::pGLContext->ValidateTextureName(texture)) { + MG_State::pGLContext->RecordError( + ErrorCode::InvalidOperation, + MakeUnique("MG_Impl/GLImpl", "BindTexture_State", "Invalid texture name")); + return; + } + if (!TextureImpl::ValidateTextureName(texture, true)) return; // ======================= Processing ================================ diff --git a/MobileGL/MG_State/EGLState/Core.cpp b/MobileGL/MG_State/EGLState/Core.cpp index 57c2c7ca..c86344c6 100644 --- a/MobileGL/MG_State/EGLState/Core.cpp +++ b/MobileGL/MG_State/EGLState/Core.cpp @@ -608,6 +608,9 @@ namespace MobileGL { if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_MINOR_VERSION); value) { contextObject.MinorVersion = *value; } + if (auto value = ParseAttribValue(attribList, EGL_CONTEXT_OPENGL_PROFILE_MASK); value) { + contextObject.OpenGLProfileMask = *value; + } const auto context = EncodeHandle(m_nextContextHandle++); m_contexts[context] = contextObject; @@ -691,6 +694,18 @@ namespace MobileGL { return ctx && ctx->Display == display; } + Bool EGLContext::IsCurrentContextOpenGLCoreProfile() const { + const std::lock_guard lock(m_mutex); + auto currentIt = m_threadCurrents.find(CurrentThreadKey()); + if (currentIt == m_threadCurrents.end()) { + return false; + } + const auto* ctx = TryGetContext(currentIt->second.Context); + return ctx && ctx->ClientAPI == EGL_OPENGL_API && + ((ctx->OpenGLProfileMask & EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT) || + ctx->MajorVersion > 3 || (ctx->MajorVersion == 3 && ctx->MinorVersion >= 1)); + } + EGLContext::EGLSurfaceHandle EGLContext::CreateWindowSurface(EGLDisplayHandle display, EGLConfigHandle config, NativeWindowType window, diff --git a/MobileGL/MG_State/EGLState/Core.h b/MobileGL/MG_State/EGLState/Core.h index 84f86841..dfe0a1ae 100644 --- a/MobileGL/MG_State/EGLState/Core.h +++ b/MobileGL/MG_State/EGLState/Core.h @@ -58,6 +58,7 @@ namespace MobileGL { EGLint* value) const; Bool ValidateContext(EGLContextHandle context) const; Bool ValidateContextOnDisplay(EGLDisplayHandle display, EGLContextHandle context) const; + Bool IsCurrentContextOpenGLCoreProfile() const; // Surface EGLSurfaceHandle CreateWindowSurface(EGLDisplayHandle display, EGLConfigHandle config, @@ -158,6 +159,7 @@ namespace MobileGL { EGLint ClientVersion = 1; EGLint MajorVersion = 1; EGLint MinorVersion = 0; + EGLint OpenGLProfileMask = 0; }; struct SurfaceObject {