summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2014-05-02 01:10:17 -0700
committerKenneth Graunke <[email protected]>2014-05-06 11:31:31 -0700
commit9701c6984d8d6570d90a15f86872b16bdba117f2 (patch)
tree3ba98963411a71a1aa929ecd1bdc9b449be29689
parentc1c1cf5f92f692c8894bd97e7139a0ec78648f29 (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.c51
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)