[Feat] (MG_State, MG_Impl, MG_Backend, MG_Util): make the border colour real sampler state

glGetSamplerParameterfv(sampler, GL_TEXTURE_BORDER_COLOR) raised INVALID_ENUM,
because MobileGL kept the border colour on the texture object and
GetSamplerParam_State had no case for it at all. That is the first thing
direct_state_access.samplers_defaults asks, so the case threw before reaching
any of the defaults it was written to check.

GL 4.6 core table 23.18 lists TEXTURE_BORDER_COLOR as sampler state, so it moves
to SamplerParameters and TextureObjectBase reaches it through the SamplerObject
it already owns - one source of truth, and a sampler object bound over a texture
now supplies its own border colour, which is what GL says should happen. The
texture params version still moves on a write, because the DirectGLES texture
sync memoises on it. glSamplerParameter{fv,Iiv,Iuiv} and their getters read and
write all four components in whichever representation the caller used, and the
three representations are kept in step so any getter has an answer. The bogus
[0,1] and [0,255] range checks are gone: GL clamps a border colour when a
fixed-point format is sampled, it does not reject it.

DirectVulkan's ResolveVkBorderColor now reads the sampler rather than the
texture. DirectGLES gained a glSamplerParameterfv in its sampler sync, and both
that and the pre-existing glTexParameterfv are gated on a new
SupportsTextureBorderClamp capability - ES 3.2 core, or EXT/OES_texture_border_clamp
before it - since without the extension every such call is INVALID_ENUM on the
driver. DriverPost gains the matching row per the POST rule, saying what a user
actually loses when it is missing.

Takes direct_state_access.samplers_defaults from failing to passing on both
backends.
This commit is contained in:
BZLZHH
2026-08-05 04:45:55 -04:00
parent 96ad7ca0cc
commit dd60ff39ce
10 changed files with 167 additions and 26 deletions
@@ -833,6 +833,10 @@ namespace MobileGL::MG_Util::BackendLoader {
if (std::strcmp(extension, "GL_EXT_texture_filter_anisotropic") == 0) {
caps.SupportsTextureFilterAnisotropy = true;
}
if (std::strcmp(extension, "GL_EXT_texture_border_clamp") == 0 ||
std::strcmp(extension, "GL_OES_texture_border_clamp") == 0) {
caps.SupportsTextureBorderClamp = true;
}
if (std::strcmp(extension, "GL_EXT_base_instance") == 0) {
caps.SupportsBaseInstance = true;
}
@@ -1014,6 +1018,10 @@ namespace MobileGL::MG_Util::BackendLoader {
}
// Only legal to query once the extension has been seen in the loop above, hence not batched
// with the unconditional probes: on a driver without it this raises GL_INVALID_ENUM.
// Core from ES 3.2 on, whatever the extension string says.
if (caps.GLESVersion.Major > 3 || (caps.GLESVersion.Major == 3 && caps.GLESVersion.Minor >= 2)) {
caps.SupportsTextureBorderClamp = true;
}
if (caps.SupportsTextureFilterAnisotropy) {
GLfloat maxTextureMaxAnisotropy = 1.0f;
glesFuncs.glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxTextureMaxAnisotropy);
@@ -1041,6 +1041,10 @@ namespace MobileGL {
// GL_EXT_texture_filter_anisotropic is present, so sampler/texture
// anisotropy may be forwarded without raising GL_INVALID_ENUM in GLES.
Bool SupportsTextureFilterAnisotropy = false;
// GL_TEXTURE_BORDER_COLOR and GL_CLAMP_TO_BORDER: ES 3.2 core, or
// EXT/OES_texture_border_clamp before that. Without it every border-colour parameter
// raises INVALID_ENUM on the driver, so the syncs have to be gated on it.
Bool SupportsTextureBorderClamp = false;
// GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT of the host driver; only queried when the
// extension above is present, and left at 1.0 (no anisotropy) otherwise.
Float MaxTextureMaxAnisotropy = 1.0f;
+11
View File
@@ -298,6 +298,17 @@ namespace MobileGL::MG_Util::SelfTest {
"not supported; no impact: the native indirect path deliberately does not "
"rely on it (shader-side emulation handles baseInstance semantics)");
}
if (caps.SupportsTextureBorderClamp) {
builder.Pass("Texture border clamp",
"supported (GL_TEXTURE_BORDER_COLOR reaches the driver, so "
"GL_CLAMP_TO_BORDER samples the colour the application set)");
} else {
builder.Warn("Texture border clamp",
"not supported (pre-ES 3.2 without GL_EXT/OES_texture_border_clamp); "
"GL_TEXTURE_BORDER_COLOR is not synced to the driver at all, so anything "
"sampling outside a GL_CLAMP_TO_BORDER texture reads the driver's default "
"border instead of the requested colour");
}
if (glesFuncs.glPatchParameteri != nullptr) {
builder.Pass("Tessellation patch parameters",
"glPatchParameteri present (GL_PATCH_VERTICES reaches the driver)");