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.
This commit is contained in:
@@ -310,18 +310,21 @@ void cso_destroy_context( struct cso_context *ctx )
|
||||
enum pipe_error cso_set_blend(struct cso_context *ctx,
|
||||
const struct pipe_blend_state *templ)
|
||||
{
|
||||
unsigned hash_key = cso_construct_key((void*)templ, sizeof(struct pipe_blend_state));
|
||||
struct cso_hash_iter iter = cso_find_state_template(ctx->cache,
|
||||
hash_key, CSO_BLEND,
|
||||
(void*)templ);
|
||||
unsigned key_size, hash_key;
|
||||
struct cso_hash_iter iter;
|
||||
void *handle;
|
||||
|
||||
key_size = templ->independent_blend_enable ? sizeof(struct pipe_blend_state) :
|
||||
(void *)&(templ->rt[1]) - (void *)templ;
|
||||
hash_key = cso_construct_key((void*)templ, key_size);
|
||||
iter = cso_find_state_template(ctx->cache, hash_key, CSO_BLEND, (void*)templ);
|
||||
|
||||
if (cso_hash_iter_is_null(iter)) {
|
||||
struct cso_blend *cso = MALLOC(sizeof(struct cso_blend));
|
||||
if (!cso)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(&cso->state, templ, sizeof(*templ));
|
||||
memcpy(&cso->state, templ, key_size);
|
||||
cso->data = ctx->pipe->create_blend_state(ctx->pipe, &cso->state);
|
||||
cso->delete_state = (cso_state_callback)ctx->pipe->delete_blend_state;
|
||||
cso->context = ctx->pipe;
|
||||
|
||||
@@ -217,7 +217,7 @@ struct pipe_depth_stencil_alpha_state
|
||||
};
|
||||
|
||||
|
||||
struct pipe_blend_state
|
||||
struct pipe_rt_blend_state
|
||||
{
|
||||
unsigned blend_enable:1;
|
||||
|
||||
@@ -229,11 +229,16 @@ struct pipe_blend_state
|
||||
unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */
|
||||
unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
|
||||
|
||||
unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */
|
||||
};
|
||||
|
||||
struct pipe_blend_state
|
||||
{
|
||||
unsigned independent_blend_enable:1;
|
||||
unsigned logicop_enable:1;
|
||||
unsigned logicop_func:4; /**< PIPE_LOGICOP_x */
|
||||
|
||||
unsigned colormask:4; /**< bitmask of PIPE_MASK_R/G/B/A */
|
||||
unsigned dither:1;
|
||||
struct pipe_rt_blend_state rt[PIPE_MAX_COLOR_BUFS];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user