From 3ff8cafac6b2d0c43d5bb8ac4392c8a80a67296f Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Fri, 10 Jul 2026 22:31:20 -0400 Subject: [PATCH] [Feat] (MG_Util/SelfTest): POST rows for polygon-mode and indexed-color-mask capabilities Surface the device features that glPolygonMode and glColorMaski depend on, so a missing capability (and the resulting FILL / draw-buffer-0 fallback) is visible in the driver POST instead of silently degrading. - DirectVulkan checklist: fillModeNonSolid (GL_LINE/GL_POINT rasterization) and independentBlend (per-draw-buffer color masks) rows, read from the physical device features already queried by the probe. - DirectGLES checklist: "Polygon mode" (GL_NV/ANGLE_polygon_mode) and "Indexed color mask" (ES 3.2 core or draw_buffers_indexed) rows, read from the cached GLESCapabilities flags. Each row passes when supported and warns (not fails) when absent, since the fallback still renders correctly. Builds clean; SanityTest sweep green (30/30). --- MobileGL/MG_Util/SelfTest/DriverPost.cpp | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/MobileGL/MG_Util/SelfTest/DriverPost.cpp b/MobileGL/MG_Util/SelfTest/DriverPost.cpp index f42d6995..d46e284d 100644 --- a/MobileGL/MG_Util/SelfTest/DriverPost.cpp +++ b/MobileGL/MG_Util/SelfTest/DriverPost.cpp @@ -234,6 +234,21 @@ namespace MobileGL::MG_Util::SelfTest { EvaluateVertexAttribLimit(builder, caps.MaxVertexAttribs, "Vertex attributes", "GL_MAX_VERTEX_ATTRIBS"); + if (caps.SupportsPolygonMode) { + builder.Pass("Polygon mode", + "glPolygonMode GL_LINE/GL_POINT available via GL_NV/ANGLE_polygon_mode"); + } else { + builder.Warn("Polygon mode", + "no GL_NV/ANGLE_polygon_mode; glPolygonMode GL_LINE/GL_POINT falls back to GL_FILL"); + } + if (caps.SupportsIndexedColorMask) { + builder.Pass("Indexed color mask", + "per-draw-buffer glColorMaski available (ES 3.2 core or draw_buffers_indexed)"); + } else { + builder.Warn("Indexed color mask", + "no indexed glColorMaski; per-draw-buffer color masks fall back to draw buffer 0"); + } + if (es31) { GLint maxVertexSsboBlocks = 0; glesFuncs.glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexSsboBlocks); @@ -1098,6 +1113,19 @@ namespace MobileGL::MG_Util::SelfTest { builder.Warn("vertexPipelineStoresAndAtomics", "unsupported; shaders that write storage buffers from the vertex stage will not work"); } + if (features.fillModeNonSolid == VK_TRUE) { + builder.Pass("fillModeNonSolid", "glPolygonMode GL_LINE/GL_POINT rasterization supported"); + } else { + builder.Warn("fillModeNonSolid", + "unsupported; glPolygonMode GL_LINE/GL_POINT falls back to GL_FILL (no wireframe/point " + "rasterization)"); + } + if (features.independentBlend == VK_TRUE) { + builder.Pass("independentBlend", "per-draw-buffer glColorMaski and indexed blend state supported"); + } else { + builder.Warn("independentBlend", + "unsupported; per-draw-buffer glColorMaski falls back to draw buffer 0 for all attachments"); + } Bool shaderDrawParameters = false; if (vkGetPhysicalDeviceFeatures2Fn != nullptr && properties.apiVersion >= VK_API_VERSION_1_1) {