From: Marek Olšák Date: Sat, 8 Nov 2014 12:02:47 +0000 (+0100) Subject: util/u_blitter: implement alpha blending for pipe->blit X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ab0643225e2718884eea874b67b55eb4aa936e53;p=mesa.git util/u_blitter: implement alpha blending for pipe->blit --- diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index 85206eab1a7..9bba07aa18e 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -104,7 +104,7 @@ struct blitter_context_priv void *fs_resolve_uint[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2]; /* Blend state. */ - void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */ + void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */ void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1]; /* Depth stencil alpha state. */ @@ -159,7 +159,7 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) struct pipe_rasterizer_state rs_state; struct pipe_sampler_state sampler_state; struct pipe_vertex_element velem[2]; - unsigned i; + unsigned i, j; ctx = CALLOC_STRUCT(blitter_context_priv); if (!ctx) @@ -208,8 +208,20 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) memset(&blend, 0, sizeof(blend)); for (i = 0; i <= PIPE_MASK_RGBA; i++) { - blend.rt[0].colormask = i; - ctx->blend[i] = pipe->create_blend_state(pipe, &blend); + for (j = 0; j < 2; j++) { + memset(&blend.rt[0], 0, sizeof(blend.rt[0])); + blend.rt[0].colormask = i; + if (j) { + blend.rt[0].blend_enable = 1; + blend.rt[0].rgb_func = PIPE_BLEND_ADD; + blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + blend.rt[0].alpha_func = PIPE_BLEND_ADD; + blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA; + blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA; + } + ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend); + } } /* depth stencil alpha state objects */ @@ -409,9 +421,10 @@ void util_blitter_destroy(struct blitter_context *blitter) struct pipe_context *pipe = blitter->pipe; int i, j, f; - for (i = 0; i <= PIPE_MASK_RGBA; i++) { - pipe->delete_blend_state(pipe, ctx->blend[i]); - } + for (i = 0; i <= PIPE_MASK_RGBA; i++) + for (j = 0; j < 2; j++) + pipe->delete_blend_state(pipe, ctx->blend[i][j]); + for (i = 0; i < Elements(ctx->blend_clear); i++) { if (ctx->blend_clear[i]) pipe->delete_blend_state(pipe, ctx->blend_clear[i]); @@ -1217,7 +1230,7 @@ static void *get_clear_blend_state(struct blitter_context_priv *ctx, /* Return an existing blend state. */ if (!clear_buffers) - return ctx->blend[0]; + return ctx->blend[0][0]; index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers); @@ -1483,7 +1496,8 @@ void util_blitter_copy_texture(struct blitter_context *blitter, /* Copy. */ util_blitter_blit_generic(blitter, dst_view, &dstbox, src_view, srcbox, src->width0, src->height0, - PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, + FALSE); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1496,7 +1510,8 @@ void util_blitter_blit_generic(struct blitter_context *blitter, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask, unsigned filter, - const struct pipe_scissor_state *scissor) + const struct pipe_scissor_state *scissor, + boolean alpha_blend) { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->base.pipe; @@ -1550,7 +1565,7 @@ void util_blitter_blit_generic(struct blitter_context *blitter, fb_state.zsbuf = NULL; if (blit_depth || blit_stencil) { - pipe->bind_blend_state(pipe, ctx->blend[0]); + pipe->bind_blend_state(pipe, ctx->blend[0][0]); if (blit_depth && blit_stencil) { pipe->bind_depth_stencil_alpha_state(pipe, @@ -1573,7 +1588,9 @@ void util_blitter_blit_generic(struct blitter_context *blitter, } } else { - pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]); + unsigned colormask = mask & PIPE_MASK_RGBA; + + pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); ctx->bind_fs_state(pipe, blitter_get_fs_texfetch_col(ctx, src->format, src_target, @@ -1786,7 +1803,8 @@ util_blitter_blit(struct blitter_context *blitter, util_blitter_blit_generic(blitter, dst_view, &info->dst.box, src_view, &info->src.box, src->width0, src->height0, info->mask, info->filter, - info->scissor_enable ? &info->scissor : NULL); + info->scissor_enable ? &info->scissor : NULL, + info->alpha_blend); pipe_surface_reference(&dst_view, NULL); pipe_sampler_view_reference(&src_view, NULL); @@ -1815,7 +1833,7 @@ void util_blitter_clear_render_target(struct blitter_context *blitter, blitter_disable_render_cond(ctx); /* bind states */ - pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]); + pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); bind_fs_write_one_cbuf(ctx); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); @@ -1867,7 +1885,7 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter, blitter_disable_render_cond(ctx); /* bind states */ - pipe->bind_blend_state(pipe, ctx->blend[0]); + pipe->bind_blend_state(pipe, ctx->blend[0][0]); if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { sr.ref_value[0] = stencil & 0xff; pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); @@ -1933,8 +1951,8 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter, blitter_disable_render_cond(ctx); /* bind states */ - pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA] : - ctx->blend[0]); + pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] : + ctx->blend[0][0]); pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); if (cbsurf) bind_fs_write_one_cbuf(ctx); @@ -2187,7 +2205,7 @@ void util_blitter_custom_color(struct blitter_context *blitter, /* bind states */ pipe->bind_blend_state(pipe, custom_blend ? custom_blend - : ctx->blend[PIPE_MASK_RGBA]); + : ctx->blend[PIPE_MASK_RGBA][0]); pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); bind_fs_write_one_cbuf(ctx); pipe->bind_vertex_elements_state(pipe, ctx->velem_state); diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 0cd173d6284..becdb029f13 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -246,7 +246,8 @@ void util_blitter_blit_generic(struct blitter_context *blitter, const struct pipe_box *srcbox, unsigned src_width0, unsigned src_height0, unsigned mask, unsigned filter, - const struct pipe_scissor_state *scissor); + const struct pipe_scissor_state *scissor, + boolean alpha_blend); void util_blitter_blit(struct blitter_context *blitter, const struct pipe_blit_info *info); diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 654b5bbc552..70ed911b7f1 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -676,6 +676,9 @@ util_try_blit_via_copy_region(struct pipe_context *ctx, return FALSE; } + if (blit->alpha_blend) + return FALSE; + ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level, blit->dst.box.x, blit->dst.box.y, blit->dst.box.z, blit->src.resource, blit->src.level, diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index 24e01560110..b2a639cb0f1 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -120,7 +120,8 @@ i915_surface_copy_render(struct pipe_context *pipe, util_blitter_blit_generic(i915->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, - PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, + FALSE); return; fallback: diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 6ea8f24cc14..b8cc316c2ac 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -667,7 +667,8 @@ static void r300_resource_copy_region(struct pipe_context *pipe, r300_blitter_begin(r300, R300_COPY); util_blitter_blit_generic(r300->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, - PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, + FALSE); r300_blitter_end(r300); pipe_surface_reference(&dst_view, NULL); diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index b0002c3b50f..22a0950a491 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -732,7 +732,8 @@ void r600_resource_copy_region(struct pipe_context *ctx, r600_blitter_begin(ctx, R600_COPY_TEXTURE); util_blitter_blit_generic(rctx->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, - PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, + FALSE); r600_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL); diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index 48972bd170c..b7450b6fcec 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -586,7 +586,8 @@ void si_resource_copy_region(struct pipe_context *ctx, si_blitter_begin(ctx, SI_COPY); util_blitter_blit_generic(sctx->blitter, dst_view, &dstbox, src_view, src_box, src_width0, src_height0, - PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); + PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL, + FALSE); si_blitter_end(ctx); pipe_surface_reference(&dst_view, NULL);