From bef610f693266c338b99511b4d1eea5d5b97644e Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Wed, 20 Jan 2010 18:26:49 +0100 Subject: gallium: prepare for per-rendertarget blend enables, writemasks, blend funcs GL 3.0 (EXT_draw_buffers2) and other APIs allow independent blend enables and write masks per render target, ARB_draw_buffers_blend (and other APIs) also allow independent blend functions. Things like dithering, logic ops however are not extended to be per rendertarget, that might be conceptually possible however it doesn't look like any API wants to expose this. --- src/mesa/state_tracker/st_atom_blend.c | 30 +++++++++++++++--------------- src/mesa/state_tracker/st_cb_clear.c | 16 ++++++++-------- 2 files changed, 23 insertions(+), 23 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 43e62c29f3e..75c14183350 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -169,30 +169,30 @@ update_blend( struct st_context *st ) } else if (st->ctx->Color.BlendEnabled) { /* blending enabled */ - blend->blend_enable = 1; + blend->rt[0].blend_enable = 1; - blend->rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); + blend->rt[0].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); if (st->ctx->Color.BlendEquationRGB == GL_MIN || st->ctx->Color.BlendEquationRGB == GL_MAX) { /* Min/max are special */ - blend->rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; } else { - blend->rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); - blend->rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); + blend->rt[0].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); + blend->rt[0].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); } - blend->alpha_func = translate_blend(st->ctx->Color.BlendEquationA); + blend->rt[0].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); if (st->ctx->Color.BlendEquationA == GL_MIN || st->ctx->Color.BlendEquationA == GL_MAX) { /* Min/max are special */ - blend->alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; } else { - blend->alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); - blend->alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + blend->rt[0].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); + blend->rt[0].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); } } else { @@ -201,13 +201,13 @@ update_blend( struct st_context *st ) /* Colormask - maybe reverse these bits? */ if (st->ctx->Color.ColorMask[0][0]) - blend->colormask |= PIPE_MASK_R; + blend->rt[0].colormask |= PIPE_MASK_R; if (st->ctx->Color.ColorMask[0][1]) - blend->colormask |= PIPE_MASK_G; + blend->rt[0].colormask |= PIPE_MASK_G; if (st->ctx->Color.ColorMask[0][2]) - blend->colormask |= PIPE_MASK_B; + blend->rt[0].colormask |= PIPE_MASK_B; if (st->ctx->Color.ColorMask[0][3]) - blend->colormask |= PIPE_MASK_A; + blend->rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend->dither = 1; diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 192d765f453..2c1be41ad83 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -227,19 +227,19 @@ clear_with_quad(GLcontext *ctx, { struct pipe_blend_state blend; memset(&blend, 0, sizeof(blend)); - blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO; - blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO; + 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.colormask |= PIPE_MASK_R; + blend.rt[0].colormask |= PIPE_MASK_R; if (ctx->Color.ColorMask[0][1]) - blend.colormask |= PIPE_MASK_G; + blend.rt[0].colormask |= PIPE_MASK_G; if (ctx->Color.ColorMask[0][2]) - blend.colormask |= PIPE_MASK_B; + blend.rt[0].colormask |= PIPE_MASK_B; if (ctx->Color.ColorMask[0][3]) - blend.colormask |= PIPE_MASK_A; + blend.rt[0].colormask |= PIPE_MASK_A; if (st->ctx->Color.DitherFlag) blend.dither = 1; } -- cgit v1.2.3 From 5fae36147e1067ac8b1eb5bcade2f9b1dbf29aa4 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Mon, 25 Jan 2010 19:27:05 +0100 Subject: st/mesa: handle EXT_draw_buffers2 per rendertarget blend enables / colormasks uses the new gallium per-rt blend functionality --- src/gallium/state_trackers/dri/dri_extensions.c | 5 ++ src/mesa/state_tracker/st_atom_blend.c | 93 ++++++++++++++++--------- src/mesa/state_tracker/st_extensions.c | 10 +++ 3 files changed, 77 insertions(+), 31 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 8b014a2a8b8..1259813a412 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -50,6 +50,7 @@ #define need_GL_EXT_blend_func_separate #define need_GL_EXT_blend_minmax #define need_GL_EXT_cull_vertex +#define need_GL_EXT_draw_buffers2 #define need_GL_EXT_fog_coord #define need_GL_EXT_framebuffer_object #define need_GL_EXT_multi_draw_arrays @@ -98,6 +99,7 @@ static const struct dri_extension card_extensions[] = { {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_draw_buffers2", GL_EXT_draw_buffers2_functions}, {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, @@ -130,6 +132,9 @@ dri_init_extensions(struct dri_context *ctx) /* The card_extensions list should be pruned according to the * capabilities of the pipe_screen. This is actually something * that can/should be done inside st_create_context(). + * XXX Not pruning is very bogus. Always all these extensions above + * will be advertized, regardless what st_init_extensions + * (which depends on the pipe cap bits) does. */ driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE); } diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 75c14183350..809b10d4799 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -152,14 +152,40 @@ translate_logicop(GLenum logicop) } } +static boolean +colormask_perrt(GLcontext *ctx) +{ + /* XXX this is ugly beyond belief */ + unsigned i; + for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { + if (!TEST_EQ_4V(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i])) { + return true; + } + } + return false; +} static void update_blend( struct st_context *st ) { struct pipe_blend_state *blend = &st->state.blend; + unsigned num_state = 1; + unsigned i; memset(blend, 0, sizeof(*blend)); + if ((st->ctx->Color.BlendEnabled && + (st->ctx->Color.BlendEnabled != ((1 << st->ctx->Const.MaxDrawBuffers) - 1))) || + colormask_perrt(st->ctx)) { + num_state = st->ctx->Const.MaxDrawBuffers; + blend->independent_blend_enable = 1; + } + /* Note it is impossible to correctly deal with EXT_blend_logic_op and + EXT_draw_buffers2/EXT_blend_equation_separate at the same time. + These combinations would require support for per-rt logicop enables + and separate alpha/rgb logicop/blend support respectively. Neither + possible in gallium nor most hardware. Assume these combinations + don't happen. */ if (st->ctx->Color.ColorLogicOpEnabled || (st->ctx->Color.BlendEnabled && st->ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) { @@ -169,30 +195,33 @@ update_blend( struct st_context *st ) } else if (st->ctx->Color.BlendEnabled) { /* blending enabled */ - blend->rt[0].blend_enable = 1; - - blend->rt[0].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); - if (st->ctx->Color.BlendEquationRGB == GL_MIN || - st->ctx->Color.BlendEquationRGB == GL_MAX) { - /* Min/max are special */ - blend->rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->rt[0].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); - blend->rt[0].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); - } + for (i = 0; i < num_state; i++) { - blend->rt[0].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); - if (st->ctx->Color.BlendEquationA == GL_MIN || - st->ctx->Color.BlendEquationA == GL_MAX) { - /* Min/max are special */ - blend->rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE; - blend->rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; - } - else { - blend->rt[0].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); - blend->rt[0].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1; + + blend->rt[i].rgb_func = translate_blend(st->ctx->Color.BlendEquationRGB); + if (st->ctx->Color.BlendEquationRGB == GL_MIN || + st->ctx->Color.BlendEquationRGB == GL_MAX) { + /* Min/max are special */ + blend->rt[i].rgb_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].rgb_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].rgb_src_factor = translate_blend(st->ctx->Color.BlendSrcRGB); + blend->rt[i].rgb_dst_factor = translate_blend(st->ctx->Color.BlendDstRGB); + } + + blend->rt[i].alpha_func = translate_blend(st->ctx->Color.BlendEquationA); + if (st->ctx->Color.BlendEquationA == GL_MIN || + st->ctx->Color.BlendEquationA == GL_MAX) { + /* Min/max are special */ + blend->rt[i].alpha_src_factor = PIPE_BLENDFACTOR_ONE; + blend->rt[i].alpha_dst_factor = PIPE_BLENDFACTOR_ONE; + } + else { + blend->rt[i].alpha_src_factor = translate_blend(st->ctx->Color.BlendSrcA); + blend->rt[i].alpha_dst_factor = translate_blend(st->ctx->Color.BlendDstA); + } } } else { @@ -200,14 +229,16 @@ update_blend( struct st_context *st ) } /* Colormask - maybe reverse these bits? */ - if (st->ctx->Color.ColorMask[0][0]) - blend->rt[0].colormask |= PIPE_MASK_R; - if (st->ctx->Color.ColorMask[0][1]) - blend->rt[0].colormask |= PIPE_MASK_G; - if (st->ctx->Color.ColorMask[0][2]) - blend->rt[0].colormask |= PIPE_MASK_B; - if (st->ctx->Color.ColorMask[0][3]) - blend->rt[0].colormask |= PIPE_MASK_A; + for (i = 0; i < num_state; i++) { + if (st->ctx->Color.ColorMask[i][0]) + blend->rt[i].colormask |= PIPE_MASK_R; + if (st->ctx->Color.ColorMask[i][1]) + blend->rt[i].colormask |= PIPE_MASK_G; + if (st->ctx->Color.ColorMask[i][2]) + blend->rt[i].colormask |= PIPE_MASK_B; + if (st->ctx->Color.ColorMask[i][3]) + blend->rt[i].colormask |= PIPE_MASK_A; + } if (st->ctx->Color.DitherFlag) blend->dither = 1; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 2a5fb27d8f3..a7411c86439 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -315,4 +315,14 @@ void st_init_extensions(struct st_context *st) if (st->pipe->render_condition) { ctx->Extensions.NV_conditional_render = GL_TRUE; } + + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_ENABLE)) { + ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; + } + +#if 0 /* not yet */ + if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) { + ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE; + } +#endif } -- cgit v1.2.3 From 9bc80ff17496feda3b47cf40e577976237f87957 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 26 Jan 2010 15:35:31 +0100 Subject: mesa/st: code cleanups for new blend functionality minor code changes, style and comment fixes --- src/mesa/state_tracker/st_atom_blend.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'src/mesa/state_tracker') diff --git a/src/mesa/state_tracker/st_atom_blend.c b/src/mesa/state_tracker/st_atom_blend.c index 809b10d4799..1511b88dd1f 100644 --- a/src/mesa/state_tracker/st_atom_blend.c +++ b/src/mesa/state_tracker/st_atom_blend.c @@ -152,17 +152,33 @@ translate_logicop(GLenum logicop) } } -static boolean -colormask_perrt(GLcontext *ctx) +/** + * Figure out if colormasks are different per rt. + */ +static GLboolean +colormask_per_rt(GLcontext *ctx) { - /* XXX this is ugly beyond belief */ + /* a bit suboptimal have to compare lots of values */ unsigned i; for (i = 1; i < ctx->Const.MaxDrawBuffers; i++) { - if (!TEST_EQ_4V(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i])) { - return true; + if (memcmp(ctx->Color.ColorMask[0], ctx->Color.ColorMask[i], 4)) { + return GL_TRUE; } } - return false; + return GL_FALSE; +} + +/** + * Figure out if blend enables are different per rt. + */ +static GLboolean +blend_per_rt(GLcontext *ctx) +{ + if (ctx->Color.BlendEnabled && + (ctx->Color.BlendEnabled != ((1 << ctx->Const.MaxDrawBuffers) - 1))) { + return GL_TRUE; + } + return GL_FALSE; } static void @@ -174,9 +190,7 @@ update_blend( struct st_context *st ) memset(blend, 0, sizeof(*blend)); - if ((st->ctx->Color.BlendEnabled && - (st->ctx->Color.BlendEnabled != ((1 << st->ctx->Const.MaxDrawBuffers) - 1))) || - colormask_perrt(st->ctx)) { + if (blend_per_rt(st->ctx) || colormask_per_rt(st->ctx)) { num_state = st->ctx->Const.MaxDrawBuffers; blend->independent_blend_enable = 1; } -- cgit v1.2.3