st/mesa: handle EXT_draw_buffers2 per rendertarget blend enables / colormasks
uses the new gallium per-rt blend functionality
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
for (i = 0; i < num_state; i++) {
|
||||
|
||||
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);
|
||||
}
|
||||
blend->rt[i].blend_enable = (st->ctx->Color.BlendEnabled >> i) & 0x1;
|
||||
|
||||
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].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;
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user