summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Petter Jansson <hpj@cl.no>2013-10-10 18:10:52 +0200
committerRobert Bragg <robert@linux.intel.com>2013-10-28 15:59:18 +0000
commit71406438c5357eb4e0ef03e940c5456a536602a0 (patch)
tree549411a482035fabe1edbf087ac8b2873e60799d
parent9bd1ee544667cfe7ecae479ec7f778446dd8f326 (diff)
downloadcogl-71406438c5357eb4e0ef03e940c5456a536602a0.tar.gz
Add API to control per-framebuffer depth writing
Add framebuffer methods cogl_framebuffer_[gs]et_depth_write_enabled() and backend bits to pass the state on to glDepthMask(). This allows us to enable or disable depth writing per-framebuffer, which if disabled saves us some work in glClear(). When rendering, the flag is combined with the pipeline's depth writing flag using a logical AND. Depth writing is enabled by default. https://bugzilla.gnome.org/show_bug.cgi?id=709827 Reviewed-by: Robert Bragg <robert@linux.intel.com>
-rw-r--r--cogl/cogl-framebuffer-private.h7
-rw-r--r--cogl/cogl-framebuffer.c36
-rw-r--r--cogl/cogl-framebuffer.h33
-rw-r--r--cogl/driver/gl/cogl-framebuffer-gl.c10
-rw-r--r--cogl/driver/gl/cogl-pipeline-opengl.c11
-rw-r--r--tests/conform/test-depth-test.c20
6 files changed, 109 insertions, 8 deletions
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index 75134123..94bc6d24 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -78,7 +78,8 @@ typedef enum _CoglFramebufferStateIndex
COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
- COGL_FRAMEBUFFER_STATE_INDEX_MAX = 8
+ COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE = 8,
+ COGL_FRAMEBUFFER_STATE_INDEX_MAX = 9
} CoglFramebufferStateIndex;
typedef enum _CoglFramebufferState
@@ -90,7 +91,8 @@ typedef enum _CoglFramebufferState
COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
- COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7
+ COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING = 1<<7,
+ COGL_FRAMEBUFFER_STATE_DEPTH_WRITE = 1<<8
} CoglFramebufferState;
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
@@ -143,6 +145,7 @@ struct _CoglFramebuffer
CoglClipState clip_state;
CoglBool dither_enabled;
+ CoglBool depth_writing_enabled;
CoglColorMask color_mask;
/* We journal the textured rectangles we want to submit to OpenGL so
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index b002f619..5c545098 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -106,6 +106,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
framebuffer->viewport_age = 0;
framebuffer->viewport_age_for_scissor_workaround = -1;
framebuffer->dither_enabled = TRUE;
+ framebuffer->depth_writing_enabled = TRUE;
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
@@ -801,6 +802,14 @@ _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
return 0;
}
+static unsigned long
+_cogl_framebuffer_compare_depth_write_state (CoglFramebuffer *a,
+ CoglFramebuffer *b)
+{
+ return a->depth_writing_enabled != b->depth_writing_enabled ?
+ COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0;
+}
+
unsigned long
_cogl_framebuffer_compare (CoglFramebuffer *a,
CoglFramebuffer *b,
@@ -849,6 +858,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
differences |=
_cogl_framebuffer_compare_front_face_winding_state (a, b);
break;
+ case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE:
+ differences |=
+ _cogl_framebuffer_compare_depth_write_state (a, b);
+ break;
default:
g_warn_if_reached ();
}
@@ -960,6 +973,29 @@ cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
}
CoglBool
+cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer)
+{
+ return framebuffer->depth_writing_enabled;
+}
+
+void
+cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer,
+ CoglBool depth_write_enabled)
+{
+ if (framebuffer->depth_writing_enabled == depth_write_enabled)
+ return;
+
+ /* XXX: Currently depth write changes don't go through the journal */
+ _cogl_framebuffer_flush_journal (framebuffer);
+
+ framebuffer->depth_writing_enabled = depth_write_enabled;
+
+ if (framebuffer->context->current_draw_buffer == framebuffer)
+ framebuffer->context->current_draw_buffer_changes |=
+ COGL_FRAMEBUFFER_STATE_DEPTH_WRITE;
+}
+
+CoglBool
cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer)
{
return framebuffer->dither_enabled;
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index 053646a3..650552b2 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -750,6 +750,39 @@ cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer,
CoglBool dither_enabled);
/**
+ * cogl_framebuffer_get_depth_write_enabled:
+ * @framebuffer: a pointer to a #CoglFramebuffer
+ *
+ * Queries whether depth buffer writing is enabled for @framebuffer. This
+ * can be controlled via cogl_framebuffer_set_depth_write_enabled().
+ *
+ * Return value: %TRUE if depth writing is enabled or %FALSE if not.
+ * Since: 1.18
+ * Stability: unstable
+ */
+CoglBool
+cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer);
+
+/**
+ * cogl_framebuffer_set_depth_write_enabled:
+ * @framebuffer: a pointer to a #CoglFramebuffer
+ * @depth_write_enabled: %TRUE to enable depth writing or %FALSE to disable
+ *
+ * Enables or disables depth buffer writing when rendering to @framebuffer.
+ * If depth writing is enabled for both the framebuffer and the rendering
+ * pipeline, and the framebuffer has an associated depth buffer, depth
+ * information will be written to this buffer during rendering.
+ *
+ * Depth buffer writing is enabled by default.
+ *
+ * Since: 1.18
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer,
+ CoglBool depth_write_enabled);
+
+/**
* cogl_framebuffer_get_color_mask:
* @framebuffer: a pointer to a #CoglFramebuffer
*
diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c
index 12c6bbd6..e34b58a5 100644
--- a/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -368,6 +368,10 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
_cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
break;
+ case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE:
+ /* Nothing to do for depth write state change; the state will always
+ * be taken into account when flushing the pipeline's depth state. */
+ break;
default:
g_warn_if_reached ();
}
@@ -916,11 +920,11 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
{
gl_buffers |= GL_DEPTH_BUFFER_BIT;
- if (ctx->depth_writing_enabled_cache != TRUE)
+ if (ctx->depth_writing_enabled_cache != framebuffer->depth_writing_enabled)
{
- GE( ctx, glDepthMask (TRUE));
+ GE( ctx, glDepthMask (framebuffer->depth_writing_enabled));
- ctx->depth_writing_enabled_cache = TRUE;
+ ctx->depth_writing_enabled_cache = framebuffer->depth_writing_enabled;
/* Make sure the DepthMask is updated when the next primitive is drawn */
ctx->current_pipeline_changes_since_flush |=
diff --git a/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/driver/gl/cogl-pipeline-opengl.c
index 4e3aedce..51db17a0 100644
--- a/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -407,6 +407,11 @@ static void
flush_depth_state (CoglContext *ctx,
CoglDepthState *depth_state)
{
+ CoglBool depth_writing_enabled = depth_state->write_enabled;
+
+ if (ctx->current_draw_buffer)
+ depth_writing_enabled &= ctx->current_draw_buffer->depth_writing_enabled;
+
if (ctx->depth_test_enabled_cache != depth_state->test_enabled)
{
if (depth_state->test_enabled == TRUE)
@@ -423,11 +428,11 @@ flush_depth_state (CoglContext *ctx,
ctx->depth_test_function_cache = depth_state->test_function;
}
- if (ctx->depth_writing_enabled_cache != depth_state->write_enabled)
+ if (ctx->depth_writing_enabled_cache != depth_writing_enabled)
{
- GE (ctx, glDepthMask (depth_state->write_enabled ?
+ GE (ctx, glDepthMask (depth_writing_enabled ?
GL_TRUE : GL_FALSE));
- ctx->depth_writing_enabled_cache = depth_state->write_enabled;
+ ctx->depth_writing_enabled_cache = depth_writing_enabled;
}
if (ctx->driver != COGL_DRIVER_GLES1 &&
diff --git a/tests/conform/test-depth-test.c b/tests/conform/test-depth-test.c
index 7dca65fc..7b9cdf77 100644
--- a/tests/conform/test-depth-test.c
+++ b/tests/conform/test-depth-test.c
@@ -28,6 +28,7 @@ typedef struct
CoglBool test_enable;
CoglDepthTestFunction test_function;
CoglBool write_enable;
+ CoglBool fb_write_enable;
float range_near;
float range_far;
} TestDepthState;
@@ -62,6 +63,7 @@ draw_rectangle (TestState *state,
cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);
+ cogl_framebuffer_set_depth_write_enabled (test_fb, rect_state->fb_write_enable);
cogl_framebuffer_push_matrix (test_fb);
cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth);
cogl_framebuffer_draw_rectangle (test_fb,
@@ -120,6 +122,7 @@ paint (TestState *state)
FALSE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
+ TRUE, /* FB depth write enable */
0, 1 /* depth range */
};
/* Furthest */
@@ -129,6 +132,7 @@ paint (TestState *state)
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
+ TRUE, /* FB depth write enable */
0, 1 /* depth range */
};
/* In the middle */
@@ -138,6 +142,7 @@ paint (TestState *state)
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_NEVER,
TRUE, /* depth write enable */
+ TRUE, /* FB depth write enable */
0, 1 /* depth range */
};
@@ -165,6 +170,19 @@ paint (TestState *state)
test_depth (state, 4, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x0000ffff); /* expected */
+
+ rect1_state.write_enable = TRUE;
+ rect1_state.fb_write_enable = FALSE;
+ test_depth (state, 4, 0, /* position */
+ &rect0_state, &rect1_state, &rect2_state,
+ 0x0000ffff); /* expected */
+
+ /* Re-enable FB depth writing to verify state flush */
+ rect1_state.write_enable = TRUE;
+ rect1_state.fb_write_enable = TRUE;
+ test_depth (state, 4, 0, /* position */
+ &rect0_state, &rect1_state, &rect2_state,
+ 0x00ff00ff); /* expected */
}
/* Check that the depth buffer values can be mapped into different
@@ -178,6 +196,7 @@ paint (TestState *state)
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
+ TRUE, /* FB depth write enable */
0.5, 1 /* depth range */
};
/* Furthest by depth, nearest by depth range */
@@ -187,6 +206,7 @@ paint (TestState *state)
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_GREATER,
TRUE, /* depth write enable */
+ TRUE, /* FB depth write enable */
0, 0.5 /* depth range */
};