diff options
Diffstat (limited to 'mesalib/src/mesa/state_tracker/st_cb_clear.c')
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_cb_clear.c | 199 |
1 files changed, 52 insertions, 147 deletions
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c index 4aa0bc18f..d01236e28 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_clear.c +++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c @@ -65,13 +65,10 @@ void st_init_clear(struct st_context *st) { - struct pipe_screen *pscreen = st->pipe->screen; - memset(&st->clear, 0, sizeof(st->clear)); st->clear.raster.gl_rasterization_rules = 1; st->clear.raster.depth_clip = 1; - st->clear.enable_ds_separate = pscreen->get_param(pscreen, PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE); } @@ -99,7 +96,9 @@ static INLINE void set_fragment_shader(struct st_context *st) { if (!st->clear.fs) - st->clear.fs = util_make_fragment_passthrough_shader(st->pipe); + st->clear.fs = + util_make_fragment_passthrough_shader(st->pipe, TGSI_SEMANTIC_GENERIC, + TGSI_INTERPOLATE_CONSTANT); cso_set_fragment_shader_handle(st->cso_context, st->clear.fs); } @@ -117,7 +116,7 @@ set_vertex_shader(struct st_context *st) if (!st->clear.vs) { const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_COLOR }; + TGSI_SEMANTIC_GENERIC }; const uint semantic_indexes[] = { 0, 0 }; st->clear.vs = util_make_vertex_passthrough_shader(st->pipe, 2, semantic_names, @@ -233,19 +232,24 @@ clear_with_quad(struct gl_context *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; if (color) { - if (ctx->Color.ColorMask[0][0]) - blend.rt[0].colormask |= PIPE_MASK_R; - if (ctx->Color.ColorMask[0][1]) - blend.rt[0].colormask |= PIPE_MASK_G; - if (ctx->Color.ColorMask[0][2]) - blend.rt[0].colormask |= PIPE_MASK_B; - if (ctx->Color.ColorMask[0][3]) - blend.rt[0].colormask |= PIPE_MASK_A; + int num_buffers = ctx->Extensions.EXT_draw_buffers2 ? + ctx->DrawBuffer->_NumColorDrawBuffers : 1; + int i; + + blend.independent_blend_enable = num_buffers > 1; + + for (i = 0; i < num_buffers; i++) { + if (ctx->Color.ColorMask[i][0]) + blend.rt[i].colormask |= PIPE_MASK_R; + if (ctx->Color.ColorMask[i][1]) + blend.rt[i].colormask |= PIPE_MASK_G; + if (ctx->Color.ColorMask[i][2]) + blend.rt[i].colormask |= PIPE_MASK_B; + if (ctx->Color.ColorMask[i][3]) + blend.rt[i].colormask |= PIPE_MASK_A; + } + if (st->ctx->Color.DitherFlag) blend.dither = 1; } @@ -333,113 +337,42 @@ clear_with_quad(struct gl_context *ctx, /** - * Determine if we need to clear the depth buffer by drawing a quad. - */ -static INLINE GLboolean -check_clear_color_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb) -{ - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return GL_TRUE; - - if (!ctx->Color.ColorMask[0][0] || - !ctx->Color.ColorMask[0][1] || - !ctx->Color.ColorMask[0][2] || - !ctx->Color.ColorMask[0][3]) - return GL_TRUE; - - return GL_FALSE; -} - - -/** - * Determine if we need to clear the combiend depth/stencil buffer by - * drawing a quad. + * Return if the scissor must be enabled during the clear. */ static INLINE GLboolean -check_clear_depth_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb) +is_scissor_enabled(struct gl_context *ctx, struct gl_renderbuffer *rb) { - const GLuint stencilMax = 0xff; - GLboolean maskStencil - = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; - - assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0); - - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return GL_TRUE; - - if (maskStencil) - return GL_TRUE; - - return GL_FALSE; + return ctx->Scissor.Enabled && + (ctx->Scissor.X > 0 || + ctx->Scissor.Y > 0 || + ctx->Scissor.Width < rb->Width || + ctx->Scissor.Height < rb->Height); } /** - * Determine if we need to clear the depth buffer by drawing a quad. + * Return if any of the color channels are masked. */ static INLINE GLboolean -check_clear_depth_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb, - boolean ds_separate) +is_color_masked(struct gl_context *ctx, int i) { - const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); - - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return GL_TRUE; - - if (!ds_separate && isDS && ctx->DrawBuffer->Visual.stencilBits > 0) - return GL_TRUE; - - return GL_FALSE; + return !ctx->Color.ColorMask[i][0] || + !ctx->Color.ColorMask[i][1] || + !ctx->Color.ColorMask[i][2] || + !ctx->Color.ColorMask[i][3]; } /** - * Determine if we need to clear the stencil buffer by drawing a quad. + * Return if any of the stencil bits are masked. */ static INLINE GLboolean -check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb, - boolean ds_separate) +is_stencil_masked(struct gl_context *ctx, struct gl_renderbuffer *rb) { - const struct st_renderbuffer *strb = st_renderbuffer(rb); - const GLboolean isDS = util_format_is_depth_and_stencil(strb->surface->format); const GLuint stencilMax = 0xff; - const GLboolean maskStencil - = (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0); - - if (maskStencil) - return GL_TRUE; - - if (ctx->Scissor.Enabled && - (ctx->Scissor.X != 0 || - ctx->Scissor.Y != 0 || - ctx->Scissor.Width < rb->Width || - ctx->Scissor.Height < rb->Height)) - return GL_TRUE; - - /* This is correct, but it is necessary to look at the depth clear - * value held in the surface when it comes time to issue the clear, - * rather than taking depth and stencil clear values from the - * current state. - */ - if (!ds_separate && isDS && ctx->DrawBuffer->Visual.depthBits > 0) - return GL_TRUE; - - return GL_FALSE; + return (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax; } @@ -449,8 +382,6 @@ check_clear_stencil_with_quad(struct gl_context *ctx, struct gl_renderbuffer *rb static void st_Clear(struct gl_context *ctx, GLbitfield mask) { - static const GLbitfield BUFFER_BITS_DS - = (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); struct st_context *st = st_context(ctx); struct gl_renderbuffer *depthRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; @@ -471,11 +402,13 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) struct gl_renderbuffer *rb = ctx->DrawBuffer->Attachment[b].Renderbuffer; struct st_renderbuffer *strb = st_renderbuffer(rb); + int colormask_index = ctx->Extensions.EXT_draw_buffers2 ? i : 0; if (!strb || !strb->surface) continue; - if (check_clear_color_with_quad( ctx, rb )) + if (is_scissor_enabled(ctx, rb) || + is_color_masked(ctx, colormask_index)) quad_buffers |= PIPE_CLEAR_COLOR; else clear_buffers |= PIPE_CLEAR_COLOR; @@ -483,41 +416,25 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) } } - if ((mask & BUFFER_BITS_DS) == BUFFER_BITS_DS && depthRb == stencilRb) { - /* clearing combined depth + stencil */ + if (mask & BUFFER_BIT_DEPTH) { struct st_renderbuffer *strb = st_renderbuffer(depthRb); if (strb->surface) { - if (check_clear_depth_stencil_with_quad(ctx, depthRb)) - quad_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + if (is_scissor_enabled(ctx, depthRb)) + quad_buffers |= PIPE_CLEAR_DEPTH; else - clear_buffers |= PIPE_CLEAR_DEPTHSTENCIL; + clear_buffers |= PIPE_CLEAR_DEPTH; } } - else { - /* separate depth/stencil clears */ - /* I don't think truly separate buffers are actually possible in gallium or hw? */ - if (mask & BUFFER_BIT_DEPTH) { - struct st_renderbuffer *strb = st_renderbuffer(depthRb); - - if (strb->surface) { - if (check_clear_depth_with_quad(ctx, depthRb, - st->clear.enable_ds_separate)) - quad_buffers |= PIPE_CLEAR_DEPTH; - else - clear_buffers |= PIPE_CLEAR_DEPTH; - } - } - if (mask & BUFFER_BIT_STENCIL) { - struct st_renderbuffer *strb = st_renderbuffer(stencilRb); + if (mask & BUFFER_BIT_STENCIL) { + struct st_renderbuffer *strb = st_renderbuffer(stencilRb); - if (strb->surface) { - if (check_clear_stencil_with_quad(ctx, stencilRb, - st->clear.enable_ds_separate)) - quad_buffers |= PIPE_CLEAR_STENCIL; - else - clear_buffers |= PIPE_CLEAR_STENCIL; - } + if (strb->surface) { + if (is_scissor_enabled(ctx, stencilRb) || + is_stencil_masked(ctx, stencilRb)) + quad_buffers |= PIPE_CLEAR_STENCIL; + else + clear_buffers |= PIPE_CLEAR_STENCIL; } } @@ -532,20 +449,8 @@ st_Clear(struct gl_context *ctx, GLbitfield mask) quad_buffers & PIPE_CLEAR_DEPTH, quad_buffers & PIPE_CLEAR_STENCIL); } 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. - */ union pipe_color_union clearColor; - if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) && - ((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; - if (ctx->DrawBuffer->_ColorDrawBuffers[0]) { struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; GLboolean is_integer = _mesa_is_enum_format_integer(rb->InternalFormat); |