mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Fix a freeze on Intel drivers when using mipmapped Canvases
Fixes #1585 Also disallow generateMipmaps on depth/stencil canvases because it's not really supported.
This commit is contained in:
@@ -69,6 +69,9 @@ Canvas::Canvas(const Settings &settings)
|
||||
filter.mipmap = defaultMipmapFilter;
|
||||
}
|
||||
|
||||
if (settings.mipmaps == MIPMAPS_AUTO && isPixelFormatDepthStencil(format))
|
||||
throw love::Exception("Automatic mipmap generation cannot be used for depth/stencil Canvases.");
|
||||
|
||||
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
|
||||
const Graphics::Capabilities &caps = gfx->getCapabilities();
|
||||
|
||||
|
||||
@@ -67,19 +67,6 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
if (texType == TEXTURE_VOLUME)
|
||||
nlayers = std::max(layers >> mip, 1);
|
||||
|
||||
GLuint tempframebuffer = 0;
|
||||
if (mip > 0)
|
||||
{
|
||||
// Some Intel drivers on Windows don't like reusing the same
|
||||
// FBO for different sized attachments, so use a temporary one
|
||||
// to clear smaller mips.
|
||||
// https://github.com/love2d/love/issues/1585
|
||||
glGenFramebuffers(1, &tempframebuffer);
|
||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, tempframebuffer);
|
||||
}
|
||||
else
|
||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, framebuffer);
|
||||
|
||||
for (int layer = nlayers - 1; layer >= 0; layer--)
|
||||
{
|
||||
for (int face = faces - 1; face >= 0; face--)
|
||||
@@ -112,9 +99,6 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tempframebuffer != 0)
|
||||
gl.deleteFramebuffer(tempframebuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,8 +262,18 @@ bool Canvas::loadVolatile()
|
||||
return false;
|
||||
}
|
||||
|
||||
// All mipmap levels need to be initialized - for color formats we can
|
||||
// clear the base mip and use glGenerateMipmap after that's done. Depth
|
||||
// and stencil formats don't always support glGenerateMipmap so we need
|
||||
// to individually clear each mip level in that case. We avoid doing that
|
||||
// for color formats because of an Intel driver bug:
|
||||
// https://github.com/love2d/love/issues/1585
|
||||
int clearmips = 1;
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
clearmips = mipmapCount;
|
||||
|
||||
// Create a canvas-local FBO used for glReadPixels as well as MSAA blitting.
|
||||
status = createFBO(fbo, texType, format, texture, texType == TEXTURE_VOLUME ? depth : layers, mipmapCount);
|
||||
status = createFBO(fbo, texType, format, texture, texType == TEXTURE_VOLUME ? depth : layers, clearmips);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
@@ -290,6 +284,9 @@ bool Canvas::loadVolatile()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (clearmips < mipmapCount && getMipmapMode() != MIPMAPS_NONE)
|
||||
generateMipmaps();
|
||||
}
|
||||
|
||||
if (!isReadable() || actualSamples > 0)
|
||||
@@ -488,6 +485,9 @@ void Canvas::generateMipmaps()
|
||||
if (getMipmapCount() == 1 || getMipmapMode() == MIPMAPS_NONE)
|
||||
throw love::Exception("generateMipmaps can only be called on a Canvas which was created with mipmaps enabled.");
|
||||
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
throw love::Exception("generateMipmaps cannot be called on a depth/stencil Canvas.");
|
||||
|
||||
gl.bindTextureToUnit(this, 0, false);
|
||||
|
||||
GLenum gltextype = OpenGL::getGLTextureType(texType);
|
||||
|
||||
@@ -587,10 +587,6 @@ void Graphics::endPass()
|
||||
if (rt.canvas->getMipmapMode() == Canvas::MIPMAPS_AUTO && rt.mipmap == 0)
|
||||
rt.canvas->generateMipmaps();
|
||||
}
|
||||
|
||||
int dsmipmap = rts.depthStencil.mipmap;
|
||||
if (depthstencil != nullptr && depthstencil->getMipmapMode() == Canvas::MIPMAPS_AUTO && dsmipmap == 0)
|
||||
depthstencil->generateMipmaps();
|
||||
}
|
||||
|
||||
void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth)
|
||||
|
||||
Reference in New Issue
Block a user