mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Feat] (MG_Backend/DirectGLES, MG_Util/Loader): wire glPolygonMode and glColorMaski into GLES sync
Neither entry point exists in unextended OpenGL ES core, so both are gated on optional extensions detected and cached at init, with a runtime fallback when absent. Loader: - Add glPolygonModeNV/glPolygonModeANGLE and glColorMaskiEXT/glColorMaskiOES to the GLES function table, loaded via a new INIT_GLES_FUNC_OPTIONAL macro that does not log an error when the driver lacks them. - Cache GLESCapabilities.SupportsPolygonMode and SupportsIndexedColorMask from whether the entry points loaded (glColorMaski is GLES 3.2 core with no extension string, so pointer presence is the reliable signal). Sync (SyncRenderState): - Color mask: uniform masks keep using the non-indexed glColorMask (works everywhere); divergent per-draw-buffer masks use glColorMaski (core / EXT / OES, whichever loaded) when SupportsIndexedColorMask, else fall back to broadcasting draw buffer 0. Mirrors the existing indexed-blend block's all-same-vs-per-buffer structure. - Polygon mode: new sync block calls glPolygonModeNV/ANGLE(GL_FRONT_AND_BACK, mode) when SupportsPolygonMode; without the extension the mode stays FILL and non-FILL requests are dropped. Library builds clean; full SanityTest sweep green (30/30).
This commit is contained in:
@@ -702,11 +702,47 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
}
|
||||
|
||||
{ // Color mask. GLES core has only the non-indexed glColorMask, so sync draw buffer 0.
|
||||
if (parameters.ColorMasks[0] != g_syncedRenderStateParameters.ColorMasks[0]) {
|
||||
const BoolVec4& colorMask = parameters.ColorMasks[0];
|
||||
g_GLESFuncs.glColorMask(ToGLBoolean(colorMask.x()), ToGLBoolean(colorMask.y()),
|
||||
ToGLBoolean(colorMask.z()), ToGLBoolean(colorMask.w()));
|
||||
{ // Color mask. Uniform masks use the non-indexed glColorMask (works everywhere); divergent
|
||||
// per-draw-buffer masks use the indexed glColorMaski when draw_buffers_indexed is
|
||||
// available, otherwise fall back to broadcasting draw buffer 0. Mirrors the blend block.
|
||||
using FBO = MG_State::GLState::FramebufferObject;
|
||||
const auto& targetMasks = parameters.ColorMasks;
|
||||
const auto& syncedMasks = g_syncedRenderStateParameters.ColorMasks;
|
||||
|
||||
Bool anyDirty = false;
|
||||
Bool allSame = true;
|
||||
for (Uint i = 0; i < FBO::MAX_DRAW_BUFFERS; ++i) {
|
||||
if (targetMasks[i] != syncedMasks[i]) anyDirty = true;
|
||||
if (i > 0 && targetMasks[i] != targetMasks[0]) allSame = false;
|
||||
}
|
||||
|
||||
if (anyDirty) {
|
||||
if (allSame || !g_GLESCapabilities.SupportsIndexedColorMask) {
|
||||
const BoolVec4& m = targetMasks[0];
|
||||
g_GLESFuncs.glColorMask(ToGLBoolean(m.x()), ToGLBoolean(m.y()), ToGLBoolean(m.z()),
|
||||
ToGLBoolean(m.w()));
|
||||
} else {
|
||||
const auto colorMaskiFn = g_GLESFuncs.glColorMaski ? g_GLESFuncs.glColorMaski
|
||||
: g_GLESFuncs.glColorMaskiEXT ? g_GLESFuncs.glColorMaskiEXT
|
||||
: g_GLESFuncs.glColorMaskiOES;
|
||||
for (Uint i = 0; i < FBO::MAX_DRAW_BUFFERS; ++i) {
|
||||
if (targetMasks[i] != syncedMasks[i]) {
|
||||
const BoolVec4& m = targetMasks[i];
|
||||
colorMaskiFn(i, ToGLBoolean(m.x()), ToGLBoolean(m.y()), ToGLBoolean(m.z()),
|
||||
ToGLBoolean(m.w()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Polygon mode. GLES core has no glPolygonMode; use NV/ANGLE_polygon_mode when present.
|
||||
// Without the extension the mode stays FILL and non-FILL requests are dropped.
|
||||
if (parameters.PolygonModeFront != g_syncedRenderStateParameters.PolygonModeFront &&
|
||||
g_GLESCapabilities.SupportsPolygonMode) {
|
||||
const auto polygonModeFn =
|
||||
g_GLESFuncs.glPolygonModeNV ? g_GLESFuncs.glPolygonModeNV : g_GLESFuncs.glPolygonModeANGLE;
|
||||
polygonModeFn(GL_FRONT_AND_BACK, parameters.PolygonModeFront);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,13 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
// Optional (extension-provided) entry points: a null pointer is expected on drivers that lack the
|
||||
// extension, so absence is not an error. The call site null-checks before use.
|
||||
#define INIT_GLES_FUNC_OPTIONAL(name) \
|
||||
do { \
|
||||
funcs.name = (MG_External::GLES::name##_PTR)procAddress(#name); \
|
||||
} while (0);
|
||||
|
||||
{
|
||||
INIT_GLES_FUNC(glActiveTexture)
|
||||
INIT_GLES_FUNC(glAttachShader)
|
||||
@@ -454,6 +461,10 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
INIT_GLES_FUNC(glGetQueryObjectui64vEXT)
|
||||
INIT_GLES_FUNC(glBindFragDataLocationEXT)
|
||||
INIT_GLES_FUNC(glMapBufferOES)
|
||||
INIT_GLES_FUNC_OPTIONAL(glPolygonModeNV)
|
||||
INIT_GLES_FUNC_OPTIONAL(glPolygonModeANGLE)
|
||||
INIT_GLES_FUNC_OPTIONAL(glColorMaskiEXT)
|
||||
INIT_GLES_FUNC_OPTIONAL(glColorMaskiOES)
|
||||
INIT_GLES_FUNC(glMultiDrawArraysIndirectEXT)
|
||||
INIT_GLES_FUNC(glMultiDrawElementsIndirectEXT)
|
||||
INIT_GLES_FUNC(glMultiDrawElementsBaseVertexEXT)
|
||||
@@ -734,6 +745,16 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
}
|
||||
}
|
||||
|
||||
// Detect optional raster/color-mask entry points by whether they loaded. glColorMaski is GLES
|
||||
// 3.2 core (no extension string), so pointer presence is the reliable signal for all of these.
|
||||
caps.SupportsPolygonMode =
|
||||
glesFuncs.glPolygonModeNV != nullptr || glesFuncs.glPolygonModeANGLE != nullptr;
|
||||
caps.SupportsIndexedColorMask = glesFuncs.glColorMaski != nullptr ||
|
||||
glesFuncs.glColorMaskiEXT != nullptr ||
|
||||
glesFuncs.glColorMaskiOES != nullptr;
|
||||
MGLOG_I(" glPolygonMode (NV/ANGLE): %s", caps.SupportsPolygonMode ? "yes" : "no");
|
||||
MGLOG_I(" indexed glColorMaski: %s", caps.SupportsIndexedColorMask ? "yes" : "no");
|
||||
|
||||
MGLOG_I("OpenGL ES capabilities:");
|
||||
glesFuncs.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &caps.UniformBufferOffsetAlignment);
|
||||
MGLOG_I(" GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: %d", caps.UniformBufferOffsetAlignment);
|
||||
|
||||
@@ -615,6 +615,11 @@ namespace MobileGL {
|
||||
GL_FUNC_TYPEDEF(void, glGetQueryObjectui64vEXT, GLuint id, GLenum pname, GLuint64* params)
|
||||
GL_FUNC_TYPEDEF(void, glBindFragDataLocationEXT, GLuint program, GLuint colorNumber, const GLchar* name)
|
||||
GL_FUNC_TYPEDEF(void*, glMapBufferOES, GLenum target, GLenum access)
|
||||
// Extension aliases for glPolygonMode (GLES core has none) and indexed glColorMaski.
|
||||
GL_FUNC_TYPEDEF(void, glPolygonModeNV, GLenum face, GLenum mode)
|
||||
GL_FUNC_TYPEDEF(void, glPolygonModeANGLE, GLenum face, GLenum mode)
|
||||
GL_FUNC_TYPEDEF(void, glColorMaskiEXT, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
|
||||
GL_FUNC_TYPEDEF(void, glColorMaskiOES, GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
|
||||
|
||||
GL_FUNC_TYPEDEF(void, glMultiDrawArraysIndirectEXT, GLenum mode, const void* indirect, GLsizei drawcount,
|
||||
GLsizei stride)
|
||||
@@ -1006,6 +1011,10 @@ namespace MobileGL {
|
||||
GL_FUNC_DECL(glGetQueryObjectui64vEXT)
|
||||
GL_FUNC_DECL(glBindFragDataLocationEXT)
|
||||
GL_FUNC_DECL(glMapBufferOES)
|
||||
GL_FUNC_DECL(glPolygonModeNV)
|
||||
GL_FUNC_DECL(glPolygonModeANGLE)
|
||||
GL_FUNC_DECL(glColorMaskiEXT)
|
||||
GL_FUNC_DECL(glColorMaskiOES)
|
||||
|
||||
GL_FUNC_DECL(glMultiDrawArraysIndirectEXT)
|
||||
GL_FUNC_DECL(glMultiDrawElementsIndirectEXT)
|
||||
@@ -1025,6 +1034,12 @@ namespace MobileGL {
|
||||
Bool SupportsBaseInstance = false;
|
||||
// GL_EXT_disjoint_timer_query is present in the extension string.
|
||||
Bool SupportsDisjointTimerQuery = false;
|
||||
// glPolygonModeNV/ANGLE loaded (GL_NV_polygon_mode / GL_ANGLE_polygon_mode). GLES core
|
||||
// has no glPolygonMode, so without this the mode stays FILL.
|
||||
Bool SupportsPolygonMode = false;
|
||||
// An indexed glColorMaski entry point loaded (GLES 3.2 core, or GL_OES/EXT_draw_buffers_indexed).
|
||||
// Without it, only the non-indexed glColorMask (draw buffer 0 broadcast) is available.
|
||||
Bool SupportsIndexedColorMask = false;
|
||||
// GL_RENDERER contains "ANGLE".
|
||||
Bool IsAngleRenderer = false;
|
||||
// GL_RENDERER contains both "ANGLE" and "llvmpipe".
|
||||
|
||||
Reference in New Issue
Block a user