1 /* 2 * Copyright © 2014 Rob Clark <[email protected]> 3 * SPDX-License-Identifier: MIT 4 * 5 * Authors: 6 * Rob Clark <[email protected]> 7 */ 8 9 #include "pipe/p_state.h" 10 #include "util/u_blend.h" 11 #include "util/u_memory.h" 12 #include "util/u_string.h" 13 14 #include "fd4_blend.h" 15 #include "fd4_context.h" 16 #include "fd4_format.h" 17 18 static enum a3xx_rb_blend_opcode blend_func(unsigned func)19blend_func(unsigned func) 20 { 21 switch (func) { 22 case PIPE_BLEND_ADD: 23 return BLEND_DST_PLUS_SRC; 24 case PIPE_BLEND_MIN: 25 return BLEND_MIN_DST_SRC; 26 case PIPE_BLEND_MAX: 27 return BLEND_MAX_DST_SRC; 28 case PIPE_BLEND_SUBTRACT: 29 return BLEND_SRC_MINUS_DST; 30 case PIPE_BLEND_REVERSE_SUBTRACT: 31 return BLEND_DST_MINUS_SRC; 32 default: 33 DBG("invalid blend func: %x", func); 34 return 0; 35 } 36 } 37 38 void * fd4_blend_state_create(struct pipe_context * pctx,const struct pipe_blend_state * cso)39fd4_blend_state_create(struct pipe_context *pctx, 40 const struct pipe_blend_state *cso) 41 { 42 struct fd4_blend_stateobj *so; 43 enum a3xx_rop_code rop = ROP_COPY; 44 bool reads_dest = false; 45 unsigned i, mrt_blend = 0; 46 47 if (cso->logicop_enable) { 48 rop = cso->logicop_func; /* maps 1:1 */ 49 reads_dest = util_logicop_reads_dest(cso->logicop_func); 50 } 51 52 so = CALLOC_STRUCT(fd4_blend_stateobj); 53 if (!so) 54 return NULL; 55 56 so->base = *cso; 57 58 for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) { 59 const struct pipe_rt_blend_state *rt; 60 61 if (cso->independent_blend_enable) 62 rt = &cso->rt[i]; 63 else 64 rt = &cso->rt[0]; 65 66 so->rb_mrt[i].blend_control = 67 A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR( 68 fd_blend_factor(rt->rgb_src_factor)) | 69 A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) | 70 A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR( 71 fd_blend_factor(rt->rgb_dst_factor)) | 72 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR( 73 fd_blend_factor(rt->alpha_src_factor)) | 74 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE( 75 blend_func(rt->alpha_func)) | 76 A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR( 77 fd_blend_factor(rt->alpha_dst_factor)); 78 79 so->rb_mrt[i].control = 80 A4XX_RB_MRT_CONTROL_ROP_CODE(rop) | 81 COND(cso->logicop_enable, A4XX_RB_MRT_CONTROL_ROP_ENABLE) | 82 A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask); 83 84 if (rt->blend_enable) { 85 so->rb_mrt[i].control |= A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE | 86 A4XX_RB_MRT_CONTROL_BLEND | 87 A4XX_RB_MRT_CONTROL_BLEND2; 88 mrt_blend |= (1 << i); 89 } 90 91 if (reads_dest) { 92 so->rb_mrt[i].control |= A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE; 93 mrt_blend |= (1 << i); 94 } 95 96 if (cso->dither) 97 so->rb_mrt[i].buf_info |= 98 A4XX_RB_MRT_BUF_INFO_DITHER_MODE(DITHER_ALWAYS); 99 } 100 101 so->rb_fs_output = 102 A4XX_RB_FS_OUTPUT_ENABLE_BLEND(mrt_blend) | 103 COND(cso->independent_blend_enable, A4XX_RB_FS_OUTPUT_INDEPENDENT_BLEND); 104 105 return so; 106 } 107