st/mesa: use new ability to clear only depth or stencil

This commit is contained in:
Roland Scheidegger 2010-05-29 00:04:14 +02:00
parent a1d5131d2e
commit 783083c3b8
2 changed files with 32 additions and 14 deletions

View file

@ -62,10 +62,12 @@ void
st_init_clear(struct st_context *st) st_init_clear(struct st_context *st)
{ {
struct pipe_context *pipe = st->pipe; struct pipe_context *pipe = st->pipe;
struct pipe_screen *pscreen = st->pipe->screen;
memset(&st->clear, 0, sizeof(st->clear)); memset(&st->clear, 0, sizeof(st->clear));
st->clear.raster.gl_rasterization_rules = 1; st->clear.raster.gl_rasterization_rules = 1;
st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE);
/* fragment shader state: color pass-through program */ /* fragment shader state: color pass-through program */
st->clear.fs = util_make_fragment_passthrough_shader(pipe); st->clear.fs = util_make_fragment_passthrough_shader(pipe);
@ -365,7 +367,8 @@ check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* Determine if we need to clear the depth buffer by drawing a quad. * Determine if we need to clear the depth buffer by drawing a quad.
*/ */
static INLINE GLboolean static INLINE GLboolean
check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb,
boolean ds_separate)
{ {
const struct st_renderbuffer *strb = st_renderbuffer(rb); const struct st_renderbuffer *strb = st_renderbuffer(rb);
const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
@ -377,7 +380,7 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
ctx->Scissor.Height < rb->Height)) ctx->Scissor.Height < rb->Height))
return GL_TRUE; return GL_TRUE;
if (isDS && ctx->DrawBuffer->Visual.stencilBits > 0) if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0)
return GL_TRUE; return GL_TRUE;
return GL_FALSE; return GL_FALSE;
@ -388,7 +391,8 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* Determine if we need to clear the stencil buffer by drawing a quad. * Determine if we need to clear the stencil buffer by drawing a quad.
*/ */
static INLINE GLboolean static INLINE GLboolean
check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb) check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb,
boolean ds_separate)
{ {
const struct st_renderbuffer *strb = st_renderbuffer(rb); const struct st_renderbuffer *strb = st_renderbuffer(rb);
const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format);
@ -415,7 +419,7 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
* rather than taking depth and stencil clear values from the * rather than taking depth and stencil clear values from the
* current state. * current state.
*/ */
if (isDS && ctx->DrawBuffer->Visual.depthBits > 0) if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0)
return GL_TRUE; return GL_TRUE;
return GL_FALSE; return GL_FALSE;
@ -495,24 +499,27 @@ st_Clear(GLcontext *ctx, GLbitfield mask)
} }
else { else {
/* separate depth/stencil clears */ /* separate depth/stencil clears */
/* I don't think truly separate buffers are actually possible in gallium or hw? */
if (mask & BUFFER_BIT_DEPTH) { if (mask & BUFFER_BIT_DEPTH) {
struct st_renderbuffer *strb = st_renderbuffer(depthRb); struct st_renderbuffer *strb = st_renderbuffer(depthRb);
if (strb->surface) { if (strb->surface) {
if (check_clear_depth_with_quad(ctx, depthRb)) if (check_clear_depth_with_quad(ctx, depthRb,
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; st->clear.enable_ds_separate))
quad_buffers |= PIPE_CLEAR_DEPTH;
else else
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; clear_buffers |= PIPE_CLEAR_DEPTH;
} }
} }
if (mask & BUFFER_BIT_STENCIL) { if (mask & BUFFER_BIT_STENCIL) {
struct st_renderbuffer *strb = st_renderbuffer(stencilRb); struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
if (strb->surface) { if (strb->surface) {
if (check_clear_stencil_with_quad(ctx, stencilRb)) if (check_clear_stencil_with_quad(ctx, stencilRb,
quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; st->clear.enable_ds_separate))
quad_buffers |= PIPE_CLEAR_STENCIL;
else else
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; clear_buffers |= PIPE_CLEAR_STENCIL;
} }
} }
} }
@ -525,12 +532,22 @@ st_Clear(GLcontext *ctx, GLbitfield mask)
quad_buffers |= clear_buffers; quad_buffers |= clear_buffers;
clear_with_quad(ctx, clear_with_quad(ctx,
quad_buffers & PIPE_CLEAR_COLOR, quad_buffers & PIPE_CLEAR_COLOR,
mask & BUFFER_BIT_DEPTH, quad_buffers & PIPE_CLEAR_DEPTH,
mask & BUFFER_BIT_STENCIL); quad_buffers & PIPE_CLEAR_STENCIL);
} else if (clear_buffers) } else if (clear_buffers) {
/* driver cannot know it can clear everything if the buffer
* is a combined depth/stencil buffer but this wasn't actually
* required from the visual. Hence fix this up to avoid potential
* read-modify-write in the driver.
*/
if (((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) &&
(depthRb == stencilRb) &&
(ctx->DrawBuffer->Visual.depthBits == 0 ||
ctx->DrawBuffer->Visual.stencilBits == 0))
clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL;
st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor, st->pipe->clear(st->pipe, clear_buffers, ctx->Color.ClearColor,
ctx->Depth.Clear, ctx->Stencil.Clear); ctx->Depth.Clear, ctx->Stencil.Clear);
}
if (mask & BUFFER_BIT_ACCUM) if (mask & BUFFER_BIT_ACCUM)
st_clear_accum_buffer(ctx, st_clear_accum_buffer(ctx,
ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer); ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer);

View file

@ -175,6 +175,7 @@ struct st_context
float vertices[4][2][4]; /**< vertex pos + color */ float vertices[4][2][4]; /**< vertex pos + color */
struct pipe_resource *vbuf; struct pipe_resource *vbuf;
unsigned vbuf_slot; unsigned vbuf_slot;
boolean enable_ds_separate;
} clear; } clear;
/** used for anything using util_draw_vertex_buffer */ /** used for anything using util_draw_vertex_buffer */