diff options
author | Kenneth Graunke <[email protected]> | 2014-05-02 01:10:17 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2014-05-06 11:31:31 -0700 |
commit | 9701c6984d8d6570d90a15f86872b16bdba117f2 (patch) | |
tree | 3ba98963411a71a1aa929ecd1bdc9b449be29689 | |
parent | c1c1cf5f92f692c8894bd97e7139a0ec78648f29 (diff) |
meta: Only clear the requested color buffers.
This path is used to implement both glClear and glClearBuffer; the
latter is only supposed to clear particular buffers. Core Mesa provides
us that information in the buffers bitmask; we must only clear buffers
mentioned there.
To accomplish this, we save/restore the color draw buffers state, and
use glDrawBuffers to restrict drawing to the relevant buffers.
Fixes Piglit's spec/!OpenGL 3.0/clearbuffer-mixed-formats and
spec/ARB_framebuffer_object/fbo-drawbuffers-none glClearBuffer tests
for drivers using meta clears (such as Broadwell).
Cc: "10.2" <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77852
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77856
Signed-off-by: Kenneth Graunke <[email protected]>
Reviewed-by: Anuj Phogat <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r-- | src/mesa/drivers/common/meta.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index 7c84c335de2..b4c30564f93 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -1655,6 +1655,48 @@ meta_glsl_clear_cleanup(struct clear_state *clear) } /** + * Given a bitfield of BUFFER_BIT_x draw buffers, call glDrawBuffers to + * set GL to only draw to those buffers. + * + * Since the bitfield has no associated order, the assignment of draw buffer + * indices to color attachment indices is rather arbitrary. + */ +static void +drawbuffers_from_bitfield(GLbitfield bits) +{ + GLenum enums[MAX_DRAW_BUFFERS]; + int i = 0; + int n; + + /* This function is only legal for color buffer bitfields. */ + assert((bits & ~BUFFER_BITS_COLOR) == 0); + + /* Make sure we don't overflow any arrays. */ + assert(_mesa_bitcount(bits) <= MAX_DRAW_BUFFERS); + + enums[0] = GL_NONE; + + if (bits & BUFFER_BIT_FRONT_LEFT) + enums[i++] = GL_FRONT_LEFT; + + if (bits & BUFFER_BIT_FRONT_RIGHT) + enums[i++] = GL_FRONT_RIGHT; + + if (bits & BUFFER_BIT_BACK_LEFT) + enums[i++] = GL_BACK_LEFT; + + if (bits & BUFFER_BIT_BACK_RIGHT) + enums[i++] = GL_BACK_RIGHT; + + for (n = 0; n < MAX_COLOR_ATTACHMENTS; n++) { + if (bits & (1 << (BUFFER_COLOR0 + n))) + enums[i++] = GL_COLOR_ATTACHMENT0 + n; + } + + _mesa_DrawBuffers(i, enums); +} + +/** * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. */ static void @@ -1690,7 +1732,9 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl) MESA_META_SELECT_FEEDBACK; } - if (!(buffers & BUFFER_BITS_COLOR)) { + if (buffers & BUFFER_BITS_COLOR) { + metaSave |= MESA_META_DRAW_BUFFERS; + } else { /* We'll use colormask to disable color writes. Otherwise, * respect color mask */ @@ -1730,7 +1774,10 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl) /* GL_COLOR_BUFFER_BIT */ if (buffers & BUFFER_BITS_COLOR) { - /* leave colormask, glDrawBuffer state as-is */ + /* Only draw to the buffers we were asked to clear. */ + drawbuffers_from_bitfield(buffers & BUFFER_BITS_COLOR); + + /* leave colormask state as-is */ /* Clears never have the color clamped. */ if (ctx->Extensions.ARB_color_buffer_float) |