mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-18 09:08:31 +09:00
[Fix] (Getter): answer the GL 4.6 limit surface honestly - tess/cull/subroutine pnames, TBuiltInResource drift, 84 UBO binding points, 64-bit GL_MAX_ELEMENT_INDEX, per-category sample truth
This commit is contained in:
@@ -1139,6 +1139,11 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// optimistic 8 behind, so the frontend promised eight clip planes and every draw with a
|
||||
// clipping program silently rendered nothing. The guarded probe below only ever widens it.
|
||||
GLint maxClipDistances = 0;
|
||||
// The cull half of the same extension, and the same "zero is a legal answer" rule: a cull
|
||||
// distance discards the whole primitive, so promising eight on a driver that has none does
|
||||
// not fail loudly, it drops every draw of a culling program.
|
||||
GLint maxCullDistances = 0;
|
||||
GLint maxCombinedClipAndCullDistances = 0;
|
||||
GLint maxViewports = 16;
|
||||
// GL_UNDEFINED_VERTEX is what stands when the probes below cannot run, and it is a legal
|
||||
// answer rather than a placeholder: with neither geometry shaders nor a viewport array
|
||||
@@ -1333,6 +1338,23 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
"rejected; reporting no clip distances");
|
||||
maxClipDistances = 0;
|
||||
}
|
||||
// GL_MAX_CULL_DISTANCES_EXT (0x82F9) and GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT
|
||||
// (0x82FA) are the same tokens as their desktop spellings and arrive with the same
|
||||
// extension, so they are probed under the same guard and the same drain sandwich.
|
||||
drainErrors();
|
||||
glesFuncs.glGetIntegerv(GL_MAX_CULL_DISTANCES, &maxCullDistances);
|
||||
if (drainErrors()) {
|
||||
MGLOG_W("GL_EXT_clip_cull_distance is advertised but GL_MAX_CULL_DISTANCES was "
|
||||
"rejected; reporting no cull distances");
|
||||
maxCullDistances = 0;
|
||||
}
|
||||
drainErrors();
|
||||
glesFuncs.glGetIntegerv(GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES, &maxCombinedClipAndCullDistances);
|
||||
if (drainErrors()) {
|
||||
MGLOG_W("GL_EXT_clip_cull_distance is advertised but "
|
||||
"GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES was rejected; deriving it from the pair");
|
||||
maxCombinedClipAndCullDistances = 0;
|
||||
}
|
||||
}
|
||||
glesFuncs.glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDims);
|
||||
// GL_LAYER_PROVOKING_VERTEX is ES 3.2 core (it arrives with geometry shaders, which is
|
||||
@@ -1562,6 +1584,14 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// A driver is free to write nonsense into an out-param it then rejects, and without the
|
||||
// extension the probe above never ran at all - so the flag, not the local, decides.
|
||||
caps.MaxClipDistances = caps.SupportsClipDistance ? std::max(maxClipDistances, 0) : 0;
|
||||
caps.MaxCullDistances = caps.SupportsClipDistance ? std::max(maxCullDistances, 0) : 0;
|
||||
// The combined limit can never be smaller than either half (GL 4.6 core 11.1.3.10 / the
|
||||
// EXT spec say so), so a driver that rejected the combined query but answered the other
|
||||
// two still gets a usable - and never over-stated - number.
|
||||
caps.MaxCombinedClipAndCullDistances =
|
||||
caps.SupportsClipDistance
|
||||
? std::max({maxCombinedClipAndCullDistances, caps.MaxClipDistances, caps.MaxCullDistances})
|
||||
: 0;
|
||||
caps.MaxViewports = maxViewports;
|
||||
caps.LayerProvokingVertex = layerProvokingVertex;
|
||||
caps.ViewportIndexProvokingVertex = viewportIndexProvokingVertex;
|
||||
@@ -1651,6 +1681,8 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
// and "this driver has no clip distances".
|
||||
MGLOG_I(" GL_MAX_CLIP_DISTANCES: %d%s", caps.MaxClipDistances,
|
||||
caps.SupportsClipDistance ? "" : " (no GL_EXT_clip_cull_distance on this driver)");
|
||||
MGLOG_I(" GL_MAX_CULL_DISTANCES: %d", caps.MaxCullDistances);
|
||||
MGLOG_I(" GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES: %d", caps.MaxCombinedClipAndCullDistances);
|
||||
MGLOG_I(" GL_MAX_VIEWPORTS: %d", caps.MaxViewports);
|
||||
MGLOG_I(" GL_MAX_VIEWPORT_DIMS: [%d, %d]", caps.MaxViewportWidth, caps.MaxViewportHeight);
|
||||
MGLOG_I(" GL_VIEWPORT_BOUNDS_RANGE: [%.3f, %.3f]", caps.ViewportBoundsRangeMin,
|
||||
|
||||
@@ -1299,6 +1299,11 @@ namespace MobileGL {
|
||||
// GL_EXT_clip_cull_distance, so a driver without it has none. See the guarded probe
|
||||
// in FillInGLESCapabilities.
|
||||
Int MaxClipDistances = 0;
|
||||
// Same contract, same reason, same extension: GL_MAX_CULL_DISTANCES_EXT and
|
||||
// GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT exist in ES only under
|
||||
// GL_EXT_clip_cull_distance, so zero is the honest answer without it.
|
||||
Int MaxCullDistances = 0;
|
||||
Int MaxCombinedClipAndCullDistances = 0;
|
||||
Int MaxViewports = 16;
|
||||
// GL_LAYER_PROVOKING_VERTEX (ES 3.2 core) and GL_VIEWPORT_INDEX_PROVOKING_VERTEX
|
||||
// (GL_OES_viewport_array). GL_UNDEFINED_VERTEX is a legal answer for both and is what
|
||||
|
||||
@@ -199,6 +199,8 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.MaxDrawBuffers = SaturateToInt(p.limits.maxFragmentOutputAttachments);
|
||||
caps.MaxColorAttachments = SaturateToInt(p.limits.maxColorAttachments);
|
||||
caps.MaxClipDistances = SaturateToInt(p.limits.maxClipDistances);
|
||||
caps.MaxCullDistances = SaturateToInt(p.limits.maxCullDistances);
|
||||
caps.MaxCombinedClipAndCullDistances = SaturateToInt(p.limits.maxCombinedClipAndCullDistances);
|
||||
caps.MaxViewports = SaturateToInt(p.limits.maxViewports);
|
||||
caps.MaxViewportWidth = SaturateToInt(p.limits.maxViewportDimensions[0]);
|
||||
caps.MaxViewportHeight = SaturateToInt(p.limits.maxViewportDimensions[1]);
|
||||
@@ -239,6 +241,7 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.SupportsFragmentStoresAndAtomics = supportedFeatures.fragmentStoresAndAtomics == VK_TRUE;
|
||||
caps.SupportsGeometryShader = supportedFeatures.geometryShader == VK_TRUE;
|
||||
caps.SupportsShaderClipDistance = supportedFeatures.shaderClipDistance == VK_TRUE;
|
||||
caps.SupportsShaderCullDistance = supportedFeatures.shaderCullDistance == VK_TRUE;
|
||||
caps.MaxShaderStorageBlockSize = static_cast<SizeT>(p.limits.maxStorageBufferRange);
|
||||
const Bool supportsShaderSubgroup = vk.vkGetPhysicalDeviceProperties2 &&
|
||||
HasUsableShaderSubgroupSupport(subgroupProps);
|
||||
@@ -319,6 +322,8 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.MaxDrawBuffers = SaturateToInt(properties.limits.maxFragmentOutputAttachments);
|
||||
caps.MaxColorAttachments = SaturateToInt(properties.limits.maxColorAttachments);
|
||||
caps.MaxClipDistances = SaturateToInt(properties.limits.maxClipDistances);
|
||||
caps.MaxCullDistances = SaturateToInt(properties.limits.maxCullDistances);
|
||||
caps.MaxCombinedClipAndCullDistances = SaturateToInt(properties.limits.maxCombinedClipAndCullDistances);
|
||||
caps.MaxViewports = SaturateToInt(properties.limits.maxViewports);
|
||||
caps.MaxViewportWidth = SaturateToInt(properties.limits.maxViewportDimensions[0]);
|
||||
caps.MaxViewportHeight = SaturateToInt(properties.limits.maxViewportDimensions[1]);
|
||||
@@ -336,6 +341,7 @@ namespace MobileGL::MG_Util::BackendLoader {
|
||||
caps.SupportsFragmentStoresAndAtomics = false;
|
||||
caps.SupportsGeometryShader = false;
|
||||
caps.SupportsShaderClipDistance = false;
|
||||
caps.SupportsShaderCullDistance = false;
|
||||
caps.MaxShaderStorageBlockSize = static_cast<SizeT>(properties.limits.maxStorageBufferRange);
|
||||
caps.SupportsShaderSubgroup = false;
|
||||
caps.SubgroupSize = 0;
|
||||
|
||||
@@ -68,6 +68,11 @@ namespace MobileGL {
|
||||
Int MaxDrawBuffers = 8;
|
||||
Int MaxColorAttachments = 8;
|
||||
Int MaxClipDistances = 8;
|
||||
// VkPhysicalDeviceLimits::maxCullDistances / maxCombinedClipAndCullDistances, gated
|
||||
// by SupportsShaderCullDistance exactly as the clip pair is gated by
|
||||
// SupportsShaderClipDistance.
|
||||
Int MaxCullDistances = 8;
|
||||
Int MaxCombinedClipAndCullDistances = 8;
|
||||
Int MaxViewports = 16;
|
||||
Int MaxViewportWidth = 16384;
|
||||
Int MaxViewportHeight = 16384;
|
||||
@@ -106,6 +111,11 @@ namespace MobileGL {
|
||||
// device has it, and without it a shader writing gl_ClipDistance is invalid. Very
|
||||
// widely supported, hence read from the device features and never assumed false.
|
||||
Bool SupportsShaderClipDistance = false;
|
||||
// VkPhysicalDeviceFeatures::shaderCullDistance, the same story one field down:
|
||||
// VulkanRenderer already ENABLES this feature where the device has it, but nobody
|
||||
// ever read the limits it unlocks, so the frontend advertised eight cull distances
|
||||
// from a literal instead of from the device.
|
||||
Bool SupportsShaderCullDistance = false;
|
||||
SizeT MaxShaderStorageBlockSize = 128 * 1024 * 1024;
|
||||
Bool SupportsShaderSubgroup = false;
|
||||
Uint32 SubgroupSize = 0;
|
||||
|
||||
Reference in New Issue
Block a user