mirror of
https://github.com/love2d/love.git
synced 2026-08-17 19:23:38 +02:00
Workaround for love.graphics.clear + love.graphics.setCanvas AMD driver bug, take two.
This commit is contained in:
@@ -438,27 +438,6 @@ void Graphics::reset()
|
||||
origin();
|
||||
}
|
||||
|
||||
void Graphics::dummyDraw()
|
||||
{
|
||||
gl.prepareDraw();
|
||||
|
||||
// Draw a triangle using a single vertex position indexed 3 times. The
|
||||
// triangle will be degenerate and won't be rasterized (so the pixel shader
|
||||
// won't be run), and an index array with a single vertex is used so the
|
||||
// vertex shader can't prevent the triangle from being degenerate by using
|
||||
// gl_VertexID.
|
||||
// NOTE: This code will have to be changed to use a vertex and index buffer,
|
||||
// for it to work with a Core Profile GL3 backend. But the bug should be
|
||||
// re-tested in that case as well.
|
||||
const GLfloat vertex[] = {0.0f, 0.0f};
|
||||
const GLushort indices[] = {0, 0, 0};
|
||||
|
||||
gl.useVertexAttribArrays(ATTRIBFLAG_POS);
|
||||
glVertexAttribPointer(ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, vertex);
|
||||
|
||||
gl.drawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, indices);
|
||||
}
|
||||
|
||||
void Graphics::clear(Colorf c)
|
||||
{
|
||||
Colorf nc = Colorf(c.r/255.0f, c.g/255.0f, c.b/255.0f, c.a/255.0f);
|
||||
@@ -468,8 +447,13 @@ void Graphics::clear(Colorf c)
|
||||
glClearColor(nc.r, nc.g, nc.b, nc.a);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (gl.bugs.clearRequiresDummyDraw)
|
||||
dummyDraw();
|
||||
if (gl.bugs.clearRequiresDriverTextureStateUpdate && Shader::current)
|
||||
{
|
||||
// This seems to be enough to fix the bug for me. Other methods I've
|
||||
// tried (e.g. dummy draws) don't work in all cases.
|
||||
glUseProgram(0);
|
||||
glUseProgram(Shader::current->getProgram());
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::clear(const std::vector<OptionalColorf> &colors)
|
||||
@@ -535,8 +519,13 @@ void Graphics::clear(const std::vector<OptionalColorf> &colors)
|
||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
if (gl.bugs.clearRequiresDummyDraw)
|
||||
dummyDraw();
|
||||
if (gl.bugs.clearRequiresDriverTextureStateUpdate && Shader::current)
|
||||
{
|
||||
// This seems to be enough to fix the bug for me. Other methods I've
|
||||
// tried (e.g. dummy draws) don't work in all cases.
|
||||
glUseProgram(0);
|
||||
glUseProgram(Shader::current->getProgram());
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::discard(const std::vector<bool> &colorbuffers, bool stencil)
|
||||
|
||||
@@ -518,8 +518,6 @@ private:
|
||||
void restoreState(const DisplayState &s);
|
||||
void restoreStateChecked(const DisplayState &s);
|
||||
|
||||
void dummyDraw();
|
||||
|
||||
void checkSetDefaultFont();
|
||||
|
||||
StrongRef<love::window::Window> currentWindow;
|
||||
|
||||
@@ -95,7 +95,7 @@ bool OpenGL::initContext()
|
||||
#if defined(LOVE_WINDOWS) || defined(LOVE_LINUX)
|
||||
// See the comment in OpenGL.h.
|
||||
if (getVendor() == VENDOR_AMD)
|
||||
bugs.clearRequiresDummyDraw = true;
|
||||
bugs.clearRequiresDriverTextureStateUpdate = true;
|
||||
#endif
|
||||
|
||||
contextInitialized = true;
|
||||
|
||||
@@ -172,14 +172,15 @@ public:
|
||||
struct Bugs
|
||||
{
|
||||
// On AMD's Windows (and probably Linux) drivers,
|
||||
// glBindFramebuffer + glClear + glBindFramebuffer won't work unless
|
||||
// there's a draw in between the glBindFramebuffer calls (or unless
|
||||
// there's some other thing that causes the driver to avoid the buggy
|
||||
// "fast path", e.g. if the scissor test is active and its rectangle
|
||||
// doesn't cover the whole framebuffer).
|
||||
// glBindFramebuffer + glClear + glBindFramebuffer + draw(fbo_tex) won't
|
||||
// work unless there's some kind of draw or state change which causes
|
||||
// the texture's contents to update (just drawing the texture won't
|
||||
// always do it).
|
||||
// Activating shader program 0 and then activating the actual program
|
||||
// seems to always 'fix' it for me.
|
||||
// Bug observed January 2016 with multiple AMD GPUs and driver versions.
|
||||
// https://love2d.org/forums/viewtopic.php?f=4&t=81496
|
||||
bool clearRequiresDummyDraw;
|
||||
bool clearRequiresDriverTextureStateUpdate;
|
||||
} bugs;
|
||||
|
||||
OpenGL();
|
||||
|
||||
@@ -194,6 +194,11 @@ public:
|
||||
|
||||
const std::map<std::string, Object *> &getBoundRetainables() const;
|
||||
|
||||
GLuint getProgram() const
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
static std::string getGLSLVersion();
|
||||
static bool isSupported();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user