1 /* 2 * Copyright © 2016 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 "fd5_blend.h" 15 #include "fd5_context.h" 16 #include "fd5_format.h" 17 18 // XXX move somewhere common.. same across a3xx/a4xx/a5xx.. 19 static enum a3xx_rb_blend_opcode blend_func(unsigned func)20blend_func(unsigned func) 21 { 22 switch (func) { 23 case PIPE_BLEND_ADD: 24 return BLEND_DST_PLUS_SRC; 25 case PIPE_BLEND_MIN: 26 return BLEND_MIN_DST_SRC; 27 case PIPE_BLEND_MAX: 28 return BLEND_MAX_DST_SRC; 29 case PIPE_BLEND_SUBTRACT: 30 return BLEND_SRC_MINUS_DST; 31 case PIPE_BLEND_REVERSE_SUBTRACT: 32 return BLEND_DST_MINUS_SRC; 33 default: 34 DBG("invalid blend func: %x", func); 35 return 0; 36 } 37 } 38 39 void * fd5_blend_state_create(struct pipe_context * pctx,const struct pipe_blend_state * cso)40fd5_blend_state_create(struct pipe_context *pctx, 41 const struct pipe_blend_state *cso) 42 { 43 struct fd5_blend_stateobj *so; 44 enum a3xx_rop_code rop = ROP_COPY; 45 bool reads_dest = false; 46 unsigned i, mrt_blend = 0; 47 48 if (cso->logicop_enable) { 49 rop = cso->logicop_func; /* maps 1:1 */ 50 reads_dest = util_logicop_reads_dest(cso->logicop_func); 51 } 52 53 so = CALLOC_STRUCT(fd5_blend_stateobj); 54 if (!so) 55 return NULL; 56 57 so->base = *cso; 58 59 so->lrz_write = true; /* unless blend enabled for any MRT */ 60 61 for (i = 0; i < ARRAY_SIZE(so->rb_mrt); i++) { 62 const struct pipe_rt_blend_state *rt; 63 64 if (cso->independent_blend_enable) 65 rt = &cso->rt[i]; 66 else 67 rt = &cso->rt[0]; 68 69 so->rb_mrt[i].blend_control = 70 A5XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR( 71 fd_blend_factor(rt->rgb_src_factor)) | 72 A5XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) | 73 A5XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR( 74 fd_blend_factor(rt->rgb_dst_factor)) | 75 A5XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR( 76 fd_blend_factor(rt->alpha_src_factor)) | 77 A5XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE( 78 blend_func(rt->alpha_func)) | 79 A5XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR( 80 fd_blend_factor(rt->alpha_dst_factor)); 81 82 so->rb_mrt[i].control = 83 A5XX_RB_MRT_CONTROL_ROP_CODE(rop) | 84 COND(cso->logicop_enable, A5XX_RB_MRT_CONTROL_ROP_ENABLE) | 85 A5XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask); 86 87 if (rt->blend_enable) { 88 so->rb_mrt[i].control |= 89 // A5XX_RB_MRT_CONTROL_READ_DEST_ENABLE | 90 A5XX_RB_MRT_CONTROL_BLEND | A5XX_RB_MRT_CONTROL_BLEND2; 91 mrt_blend |= (1 << i); 92 so->lrz_write = false; 93 } 94 95 if (reads_dest) { 96 // so->rb_mrt[i].control |= 97 // A5XX_RB_MRT_CONTROL_READ_DEST_ENABLE; 98 mrt_blend |= (1 << i); 99 } 100 101 // if (cso->dither) 102 // so->rb_mrt[i].buf_info |= 103 // A5XX_RB_MRT_BUF_INFO_DITHER_MODE(DITHER_ALWAYS); 104 } 105 106 so->rb_blend_cntl = 107 A5XX_RB_BLEND_CNTL_ENABLE_BLEND(mrt_blend) | 108 COND(cso->alpha_to_coverage, A5XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE) | 109 COND(cso->independent_blend_enable, A5XX_RB_BLEND_CNTL_INDEPENDENT_BLEND); 110 so->sp_blend_cntl = 111 A5XX_SP_BLEND_CNTL_ENABLE_BLEND(mrt_blend) | 112 A5XX_SP_BLEND_CNTL_UNK8 | 113 COND(cso->alpha_to_coverage, A5XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE); 114 115 return so; 116 } 117