[Feat] (MG_State, MG_Impl/GLImpl): per-target default texture objects (name 0) - binding 0 binds a real per-context default object (the initial binding of every unit/target slot, rebound on delete of a bound texture), so glTexImage*/glTexParameter*/glGetTex* on it work like any texture while glIsTexture(0)/Gen/Delete keep excluding it and TexStorage* rejects it per spec; backends skip image-less defaults as cheaply as the old null slots (DirectGLES per-draw sync/bind loops, DirectVulkan sampler-fallback resolve); also accept the full advertised GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS range in glActiveTexture, allow zero-layer TexImage3DMultisample, and let glTexBuffer(buffer=0) detach - the texture section of GL CTS per-case state reset (gluStateReset) now runs clean

This commit is contained in:
2026-07-16 23:36:43 -04:00
parent efd7b47388
commit 076cd0d19d
11 changed files with 435 additions and 60 deletions
@@ -430,7 +430,9 @@ namespace MobileGL::MG_Backend::DirectGLES {
auto& unit = MG_State::pGLContext->GetTextureUnitObject(index);
for (const auto& bindingSlot : unit.GetAllBindingSlots()) {
auto& textureObject = bindingSlot.GetBoundObject();
if (textureObject) {
// An image-less default texture (name 0) is the slot's initial / "unbound"
// state; it has nothing to sync, so skip it as cheaply as the old null slot.
if (textureObject && !MG_State::GLState::IsUndefinedDefaultTexture(textureObject.get())) {
SyncTextureObjectToBackend(textureObject);
}
}
@@ -1025,6 +1027,10 @@ namespace MobileGL::MG_Backend::DirectGLES {
for (const auto& bindingSlot : textureUnit.GetAllBindingSlots()) {
const auto& textureObject = bindingSlot.GetBoundObject();
if (!textureObject) continue;
// A default texture (name 0) that was never given an image is the initial /
// "unbound" state of the slot; skip it exactly like the old null slot so bind-0
// heavy apps pay nothing per draw for the always-populated slots.
if (MG_State::GLState::IsUndefinedDefaultTexture(textureObject.get())) continue;
// Bind texture object
auto target = textureObject->GetTarget();