Added a workaround for an AMD driver bug where setCanvas + clear + setCanvas doesn't work.

This commit is contained in:
Alex Szpakowski
2016-01-09 17:14:05 -04:00
parent 9d6ff6e5de
commit 4f093e7fac
4 changed files with 50 additions and 0 deletions
+27
View File
@@ -438,6 +438,27 @@ 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);
@@ -446,6 +467,9 @@ 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();
}
void Graphics::clear(const std::vector<OptionalColorf> &colors)
@@ -510,6 +534,9 @@ void Graphics::clear(const std::vector<OptionalColorf> &colors)
else
glDrawBuffer(GL_COLOR_ATTACHMENT0);
}
if (gl.bugs.clearRequiresDummyDraw)
dummyDraw();
}
void Graphics::discard(const std::vector<bool> &colorbuffers, bool stencil)
+2
View File
@@ -518,6 +518,8 @@ private:
void restoreState(const DisplayState &s);
void restoreStateChecked(const DisplayState &s);
void dummyDraw();
void checkSetDefaultFont();
StrongRef<love::window::Window> currentWindow;
+8
View File
@@ -90,6 +90,14 @@ bool OpenGL::initContext()
initVendor();
initMatrices();
bugs = {};
#if defined(LOVE_WINDOWS) || defined(LOVE_LINUX)
// See the comment in OpenGL.h.
if (getVendor() == VENDOR_AMD)
bugs.clearRequiresDummyDraw = true;
#endif
contextInitialized = true;
return true;
+13
View File
@@ -169,6 +169,19 @@ public:
int framebufferBinds;
} stats;
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).
// Bug observed January 2016 with multiple AMD GPUs and driver versions.
// https://love2d.org/forums/viewtopic.php?f=4&t=81496
bool clearRequiresDummyDraw;
} bugs;
OpenGL();
/**