@ -3548,6 +3548,14 @@ static inline int conv_dst_blend(int blend_factor)
return blend_factor ;
return blend_factor ;
}
}
static inline bool is_const_blend ( int blend_factor )
{
return ( blend_factor = = PIPE_BLENDFACTOR_CONST_COLOR | |
blend_factor = = PIPE_BLENDFACTOR_CONST_ALPHA | |
blend_factor = = PIPE_BLENDFACTOR_INV_CONST_COLOR | |
blend_factor = = PIPE_BLENDFACTOR_INV_CONST_ALPHA ) ;
}
static void vrend_hw_emit_blend ( struct vrend_context * ctx , struct pipe_blend_state * state )
static void vrend_hw_emit_blend ( struct vrend_context * ctx , struct pipe_blend_state * state )
{
{
if ( state - > logicop_enable ! = ctx - > sub - > hw_blend_state . logicop_enable ) {
if ( state - > logicop_enable ! = ctx - > sub - > hw_blend_state . logicop_enable ) {
@ -3642,57 +3650,52 @@ static void vrend_patch_blend_state(struct vrend_context *ctx)
{
{
struct pipe_blend_state new_state = ctx - > sub - > blend_state ;
struct pipe_blend_state new_state = ctx - > sub - > blend_state ;
struct pipe_blend_state * state = & ctx - > sub - > blend_state ;
struct pipe_blend_state * state = & ctx - > sub - > blend_state ;
bool dest_alpha_only = false , dest_has_no_alpha = false ;
bool swizzle_blend_color = false ;
struct pipe_blend_color blend_color = ctx - > sub - > blend_color ;
struct pipe_blend_color blend_color = ctx - > sub - > blend_color ;
int i ;
int i ;
if ( ctx - > sub - > nr_cbufs = = 0 )
if ( ctx - > sub - > nr_cbufs = = 0 )
return ;
return ;
for ( i = 0 ; i < ctx - > sub - > nr_cbufs ; i + + ) {
for ( i = 0 ; i < ( state - > independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1 ) ; i + + ) {
if ( ! ctx - > sub - > surf [ i ] )
if ( i < ctx - > sub - > nr_cbufs & & ctx - > sub - > surf [ i ] ) {
continue ;
if ( vrend_format_is_emulated_alpha ( ctx - > sub - > surf [ i ] - > format ) ) {
if ( state - > rt [ i ] . blend_enable ) {
if ( vrend_format_is_emulated_alpha ( ctx - > sub - > surf [ i ] - > format ) ) {
new_state . rt [ i ] . rgb_src_factor = conv_a8_blend ( state - > rt [ i ] . alpha_src_factor ) ;
dest_alpha_only = true ;
new_state . rt [ i ] . rgb_dst_factor = conv_a8_blend ( state - > rt [ i ] . alpha_dst_factor ) ;
}
new_state . rt [ i ] . alpha_src_factor = PIPE_BLENDFACTOR_ZERO ;
new_state . rt [ i ] . alpha_dst_factor = PIPE_BLENDFACTOR_ZERO ;
if ( ! util_format_has_alpha ( ctx - > sub - > surf [ i ] - > format ) ) {
}
dest_has_no_alpha = true ;
new_state . rt [ i ] . colormask = 0 ;
if ( state - > rt [ i ] . colormask & PIPE_MASK_A )
new_state . rt [ i ] . colormask | = PIPE_MASK_R ;
if ( is_const_blend ( new_state . rt [ i ] . rgb_src_factor ) | |
is_const_blend ( new_state . rt [ i ] . rgb_dst_factor ) ) {
swizzle_blend_color = true ;
}
} else if ( ! util_format_has_alpha ( ctx - > sub - > surf [ i ] - > format ) ) {
if ( ! ( is_dst_blend ( state - > rt [ i ] . rgb_src_factor ) | |
is_dst_blend ( state - > rt [ i ] . rgb_dst_factor ) | |
is_dst_blend ( state - > rt [ i ] . alpha_src_factor ) | |
is_dst_blend ( state - > rt [ i ] . alpha_dst_factor ) ) )
continue ;
new_state . rt [ i ] . rgb_src_factor = conv_dst_blend ( state - > rt [ i ] . rgb_src_factor ) ;
new_state . rt [ i ] . rgb_dst_factor = conv_dst_blend ( state - > rt [ i ] . rgb_dst_factor ) ;
new_state . rt [ i ] . alpha_src_factor = conv_dst_blend ( state - > rt [ i ] . alpha_src_factor ) ;
new_state . rt [ i ] . alpha_dst_factor = conv_dst_blend ( state - > rt [ i ] . alpha_dst_factor ) ;
}
}
}
}
}
if ( dest_alpha_only ) {
vrend_hw_emit_blend ( ctx , & new_state ) ;
for ( i = 0 ; i < ( state - > independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1 ) ; i + + ) {
if ( state - > rt [ i ] . blend_enable ) {
if ( swizzle_blend_color ) {
new_state . rt [ i ] . rgb_src_factor = conv_a8_blend ( state - > rt [ i ] . alpha_src_factor ) ;
new_state . rt [ i ] . rgb_dst_factor = conv_a8_blend ( state - > rt [ i ] . alpha_dst_factor ) ;
new_state . rt [ i ] . alpha_src_factor = PIPE_BLENDFACTOR_ZERO ;
new_state . rt [ i ] . alpha_dst_factor = PIPE_BLENDFACTOR_ZERO ;
}
new_state . rt [ i ] . colormask = 0 ;
if ( state - > rt [ i ] . colormask & PIPE_MASK_A )
new_state . rt [ i ] . colormask | = PIPE_MASK_R ;
}
blend_color . color [ 0 ] = blend_color . color [ 3 ] ;
blend_color . color [ 0 ] = blend_color . color [ 3 ] ;
blend_color . color [ 1 ] = 0.0f ;
blend_color . color [ 1 ] = 0.0f ;
blend_color . color [ 2 ] = 0.0f ;
blend_color . color [ 2 ] = 0.0f ;
blend_color . color [ 3 ] = 0.0f ;
blend_color . color [ 3 ] = 0.0f ;
} else if ( dest_has_no_alpha ) {
for ( i = 0 ; i < ( state - > independent_blend_enable ? PIPE_MAX_COLOR_BUFS : 1 ) ; i + + ) {
if ( ! ( is_dst_blend ( state - > rt [ i ] . rgb_src_factor ) | |
is_dst_blend ( state - > rt [ i ] . rgb_dst_factor ) | |
is_dst_blend ( state - > rt [ i ] . alpha_src_factor ) | |
is_dst_blend ( state - > rt [ i ] . alpha_dst_factor ) ) )
continue ;
new_state . rt [ i ] . rgb_src_factor = conv_dst_blend ( state - > rt [ i ] . rgb_src_factor ) ;
new_state . rt [ i ] . rgb_dst_factor = conv_dst_blend ( state - > rt [ i ] . rgb_dst_factor ) ;
new_state . rt [ i ] . alpha_src_factor = conv_dst_blend ( state - > rt [ i ] . alpha_src_factor ) ;
new_state . rt [ i ] . alpha_dst_factor = conv_dst_blend ( state - > rt [ i ] . alpha_dst_factor ) ;
}
}
}
vrend_hw_emit_blend ( ctx , & new_state ) ;
glBlendColor ( blend_color . color [ 0 ] ,
glBlendColor ( blend_color . color [ 0 ] ,
blend_color . color [ 1 ] ,
blend_color . color [ 1 ] ,
blend_color . color [ 2 ] ,
blend_color . color [ 2 ] ,