Detach textures from framebuffers before deleting

GL drivers keep internal references to textures attached to
framebuffers. Deleting a texture while still attached can cause
use-after-free in driver memory, observed as crashes on NVIDIA
during rapid preset switching or window resize.

Detach all textures before deletion in both ~Framebuffer() and
SetSize(), using a three-phase detach → resize → reattach pattern
in SetSize() to avoid referencing stale texture IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
struktured
2026-03-29 17:29:12 -04:00
committed by Kai Blaschke
parent 16f40af10e
commit 98101f56fe

View File

@ -24,11 +24,11 @@ Framebuffer::~Framebuffer()
{
if (!m_framebufferIds.empty())
{
// Delete attached textures first
m_attachments.clear();
// Delete FBOs first — this also releases driver references to attached textures.
glDeleteFramebuffers(static_cast<int>(m_framebufferIds.size()), m_framebufferIds.data());
m_framebufferIds.clear();
m_attachments.clear();
}
}
@ -94,6 +94,8 @@ bool Framebuffer::SetSize(int width, int height)
Bind(attachments.first);
for (auto& texture : attachments.second)
{
// Detach old texture, resize (destroys old and creates new), reattach new.
glFramebufferTexture2D(GL_FRAMEBUFFER, texture.first, GL_TEXTURE_2D, 0, 0);
texture.second->SetSize(width, height);
glFramebufferTexture2D(GL_FRAMEBUFFER, texture.first, GL_TEXTURE_2D, texture.second->Texture()->TextureID(), 0);
}