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> (cherry picked from commit 71406438c5357eb4e0ef03e940c5456a536602a0)
This commit is contained in:
parent
18486a6aa9
commit
a8e04a7d6b
@ -78,7 +78,8 @@ typedef enum _CoglFramebufferStateIndex
|
|||||||
COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
|
COGL_FRAMEBUFFER_STATE_INDEX_PROJECTION = 5,
|
||||||
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
|
COGL_FRAMEBUFFER_STATE_INDEX_COLOR_MASK = 6,
|
||||||
COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING = 7,
|
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;
|
} CoglFramebufferStateIndex;
|
||||||
|
|
||||||
typedef enum _CoglFramebufferState
|
typedef enum _CoglFramebufferState
|
||||||
@ -90,7 +91,8 @@ typedef enum _CoglFramebufferState
|
|||||||
COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
|
COGL_FRAMEBUFFER_STATE_MODELVIEW = 1<<4,
|
||||||
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
|
COGL_FRAMEBUFFER_STATE_PROJECTION = 1<<5,
|
||||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK = 1<<6,
|
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;
|
} CoglFramebufferState;
|
||||||
|
|
||||||
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
|
#define COGL_FRAMEBUFFER_STATE_ALL ((1<<COGL_FRAMEBUFFER_STATE_INDEX_MAX) - 1)
|
||||||
@ -143,6 +145,7 @@ struct _CoglFramebuffer
|
|||||||
CoglClipState clip_state;
|
CoglClipState clip_state;
|
||||||
|
|
||||||
CoglBool dither_enabled;
|
CoglBool dither_enabled;
|
||||||
|
CoglBool depth_writing_enabled;
|
||||||
CoglColorMask color_mask;
|
CoglColorMask color_mask;
|
||||||
|
|
||||||
/* We journal the textured rectangles we want to submit to OpenGL so
|
/* We journal the textured rectangles we want to submit to OpenGL so
|
||||||
|
@ -114,6 +114,7 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
|
|||||||
framebuffer->viewport_age = 0;
|
framebuffer->viewport_age = 0;
|
||||||
framebuffer->viewport_age_for_scissor_workaround = -1;
|
framebuffer->viewport_age_for_scissor_workaround = -1;
|
||||||
framebuffer->dither_enabled = TRUE;
|
framebuffer->dither_enabled = TRUE;
|
||||||
|
framebuffer->depth_writing_enabled = TRUE;
|
||||||
|
|
||||||
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
|
framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
|
||||||
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
|
framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
|
||||||
@ -1103,6 +1104,14 @@ _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
|
|||||||
return 0;
|
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
|
unsigned long
|
||||||
_cogl_framebuffer_compare (CoglFramebuffer *a,
|
_cogl_framebuffer_compare (CoglFramebuffer *a,
|
||||||
CoglFramebuffer *b,
|
CoglFramebuffer *b,
|
||||||
@ -1151,6 +1160,10 @@ _cogl_framebuffer_compare (CoglFramebuffer *a,
|
|||||||
differences |=
|
differences |=
|
||||||
_cogl_framebuffer_compare_front_face_winding_state (a, b);
|
_cogl_framebuffer_compare_front_face_winding_state (a, b);
|
||||||
break;
|
break;
|
||||||
|
case COGL_FRAMEBUFFER_STATE_INDEX_DEPTH_WRITE:
|
||||||
|
differences |=
|
||||||
|
_cogl_framebuffer_compare_depth_write_state (a, b);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
@ -1261,6 +1274,29 @@ cogl_framebuffer_set_color_mask (CoglFramebuffer *framebuffer,
|
|||||||
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
COGL_FRAMEBUFFER_STATE_COLOR_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
CoglBool
|
||||||
cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer)
|
cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer)
|
||||||
{
|
{
|
||||||
|
@ -757,6 +757,39 @@ void
|
|||||||
cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer,
|
cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer,
|
||||||
CoglBool dither_enabled);
|
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:
|
* cogl_framebuffer_get_color_mask:
|
||||||
* @framebuffer: a pointer to a #CoglFramebuffer
|
* @framebuffer: a pointer to a #CoglFramebuffer
|
||||||
|
@ -368,6 +368,10 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
|
|||||||
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
|
case COGL_FRAMEBUFFER_STATE_INDEX_FRONT_FACE_WINDING:
|
||||||
_cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
|
_cogl_framebuffer_gl_flush_front_face_winding_state (draw_buffer);
|
||||||
break;
|
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:
|
default:
|
||||||
g_warn_if_reached ();
|
g_warn_if_reached ();
|
||||||
}
|
}
|
||||||
@ -916,11 +920,11 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
|
|||||||
{
|
{
|
||||||
gl_buffers |= GL_DEPTH_BUFFER_BIT;
|
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 */
|
/* Make sure the DepthMask is updated when the next primitive is drawn */
|
||||||
ctx->current_pipeline_changes_since_flush |=
|
ctx->current_pipeline_changes_since_flush |=
|
||||||
|
@ -407,6 +407,11 @@ static void
|
|||||||
flush_depth_state (CoglContext *ctx,
|
flush_depth_state (CoglContext *ctx,
|
||||||
CoglDepthState *depth_state)
|
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 (ctx->depth_test_enabled_cache != depth_state->test_enabled)
|
||||||
{
|
{
|
||||||
if (depth_state->test_enabled == TRUE)
|
if (depth_state->test_enabled == TRUE)
|
||||||
@ -423,11 +428,11 @@ flush_depth_state (CoglContext *ctx,
|
|||||||
ctx->depth_test_function_cache = depth_state->test_function;
|
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));
|
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 &&
|
if (ctx->driver != COGL_DRIVER_GLES1 &&
|
||||||
|
@ -30,6 +30,7 @@ typedef struct
|
|||||||
CoglBool test_enable;
|
CoglBool test_enable;
|
||||||
CoglDepthTestFunction test_function;
|
CoglDepthTestFunction test_function;
|
||||||
CoglBool write_enable;
|
CoglBool write_enable;
|
||||||
|
CoglBool fb_write_enable;
|
||||||
float range_near;
|
float range_near;
|
||||||
float range_far;
|
float range_far;
|
||||||
} TestDepthState;
|
} TestDepthState;
|
||||||
@ -67,6 +68,8 @@ draw_rectangle (TestState *state,
|
|||||||
{
|
{
|
||||||
cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);
|
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_push_matrix (test_fb);
|
||||||
cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth);
|
cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth);
|
||||||
cogl_framebuffer_draw_rectangle (test_fb,
|
cogl_framebuffer_draw_rectangle (test_fb,
|
||||||
@ -140,6 +143,7 @@ paint (TestState *state)
|
|||||||
FALSE, /* depth test enable */
|
FALSE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 1 /* depth range */
|
0, 1 /* depth range */
|
||||||
};
|
};
|
||||||
/* Furthest */
|
/* Furthest */
|
||||||
@ -149,6 +153,7 @@ paint (TestState *state)
|
|||||||
TRUE, /* depth test enable */
|
TRUE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 1 /* depth range */
|
0, 1 /* depth range */
|
||||||
};
|
};
|
||||||
/* In the middle */
|
/* In the middle */
|
||||||
@ -158,6 +163,7 @@ paint (TestState *state)
|
|||||||
TRUE, /* depth test enable */
|
TRUE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_NEVER,
|
COGL_DEPTH_TEST_FUNCTION_NEVER,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 1 /* depth range */
|
0, 1 /* depth range */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -190,6 +196,21 @@ paint (TestState *state)
|
|||||||
&rect0_state, &rect1_state, &rect2_state,
|
&rect0_state, &rect1_state, &rect2_state,
|
||||||
FALSE, /* legacy mode */
|
FALSE, /* legacy mode */
|
||||||
0x0000ffff); /* expected */
|
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,
|
||||||
|
FALSE, /* legacy mode */
|
||||||
|
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,
|
||||||
|
FALSE, /* legacy mode */
|
||||||
|
0x00ff00ff); /* expected */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the depth buffer values can be mapped into different
|
/* Check that the depth buffer values can be mapped into different
|
||||||
@ -203,6 +224,7 @@ paint (TestState *state)
|
|||||||
TRUE, /* depth test enable */
|
TRUE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0.5, 1 /* depth range */
|
0.5, 1 /* depth range */
|
||||||
};
|
};
|
||||||
/* Furthest by depth, nearest by depth range */
|
/* Furthest by depth, nearest by depth range */
|
||||||
@ -212,6 +234,7 @@ paint (TestState *state)
|
|||||||
TRUE, /* depth test enable */
|
TRUE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_GREATER,
|
COGL_DEPTH_TEST_FUNCTION_GREATER,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 0.5 /* depth range */
|
0, 0.5 /* depth range */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -232,6 +255,7 @@ paint (TestState *state)
|
|||||||
FALSE, /* depth test enable */
|
FALSE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_LESS,
|
COGL_DEPTH_TEST_FUNCTION_LESS,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 1 /* depth range */
|
0, 1 /* depth range */
|
||||||
};
|
};
|
||||||
/* Furthest */
|
/* Furthest */
|
||||||
@ -241,6 +265,7 @@ paint (TestState *state)
|
|||||||
FALSE, /* depth test enable */
|
FALSE, /* depth test enable */
|
||||||
COGL_DEPTH_TEST_FUNCTION_LESS,
|
COGL_DEPTH_TEST_FUNCTION_LESS,
|
||||||
TRUE, /* depth write enable */
|
TRUE, /* depth write enable */
|
||||||
|
TRUE, /* FB depth write enable */
|
||||||
0, 1 /* depth range */
|
0, 1 /* depth range */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user