mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-14 14:28:08 +02:00
st/mesa: use new ability to clear only depth or stencil
This commit is contained in:
parent
a1d5131d2e
commit
783083c3b8
2 changed files with 32 additions and 14 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue