1 /********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26 #include "util/u_inlines.h" 27 #include "pipe/p_defines.h" 28 #include "util/u_math.h" 29 #include "util/u_memory.h" 30 31 #include "svga_context.h" 32 33 #include "svga_hw_reg.h" 34 35 36 static INLINE unsigned 37 svga_translate_blend_factor(unsigned factor) 38 { 39 switch (factor) { 40 case PIPE_BLENDFACTOR_ZERO: return SVGA3D_BLENDOP_ZERO; 41 case PIPE_BLENDFACTOR_SRC_ALPHA: return SVGA3D_BLENDOP_SRCALPHA; 42 case PIPE_BLENDFACTOR_ONE: return SVGA3D_BLENDOP_ONE; 43 case PIPE_BLENDFACTOR_SRC_COLOR: return SVGA3D_BLENDOP_SRCCOLOR; 44 case PIPE_BLENDFACTOR_INV_SRC_COLOR: return SVGA3D_BLENDOP_INVSRCCOLOR; 45 case PIPE_BLENDFACTOR_DST_COLOR: return SVGA3D_BLENDOP_DESTCOLOR; 46 case PIPE_BLENDFACTOR_INV_DST_COLOR: return SVGA3D_BLENDOP_INVDESTCOLOR; 47 case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return SVGA3D_BLENDOP_INVSRCALPHA; 48 case PIPE_BLENDFACTOR_DST_ALPHA: return SVGA3D_BLENDOP_DESTALPHA; 49 case PIPE_BLENDFACTOR_INV_DST_ALPHA: return SVGA3D_BLENDOP_INVDESTALPHA; 50 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT; 51 case PIPE_BLENDFACTOR_CONST_COLOR: return SVGA3D_BLENDOP_BLENDFACTOR; 52 case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR; 53 case PIPE_BLENDFACTOR_CONST_ALPHA: return SVGA3D_BLENDOP_BLENDFACTOR; /* ? */ 54 case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return SVGA3D_BLENDOP_INVBLENDFACTOR; /* ? */ 55 default: 56 assert(0); 57 return SVGA3D_BLENDOP_ZERO; 58 } 59 } 60 61 static INLINE unsigned 62 svga_translate_blend_func(unsigned mode) 63 { 64 switch (mode) { 65 case PIPE_BLEND_ADD: return SVGA3D_BLENDEQ_ADD; 66 case PIPE_BLEND_SUBTRACT: return SVGA3D_BLENDEQ_SUBTRACT; 67 case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT; 68 case PIPE_BLEND_MIN: return SVGA3D_BLENDEQ_MINIMUM; 69 case PIPE_BLEND_MAX: return SVGA3D_BLENDEQ_MAXIMUM; 70 default: 71 assert(0); 72 return SVGA3D_BLENDEQ_ADD; 73 } 74 } 75 76 77 static void * 78 svga_create_blend_state(struct pipe_context *pipe, 79 const struct pipe_blend_state *templ) 80 { 81 struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state ); 82 unsigned i; 83 84 85 /* Fill in the per-rendertarget blend state. We currently only 86 * have one rendertarget. 87 */ 88 for (i = 0; i < 1; i++) { 89 /* No way to set this in SVGA3D, and no way to correctly implement it on 90 * top of D3D9 API. Instead we try to simulate with various blend modes. 91 */ 92 if (templ->logicop_enable) { 93 switch (templ->logicop_func) { 94 case PIPE_LOGICOP_XOR: 95 case PIPE_LOGICOP_INVERT: 96 blend->need_white_fragments = TRUE; 97 blend->rt[i].blend_enable = TRUE; 98 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; 99 blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE; 100 blend->rt[i].blendeq = SVGA3D_BLENDEQ_SUBTRACT; 101 break; 102 case PIPE_LOGICOP_CLEAR: 103 blend->rt[i].blend_enable = TRUE; 104 blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO; 105 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; 106 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; 107 break; 108 case PIPE_LOGICOP_COPY: 109 blend->rt[i].blend_enable = FALSE; 110 break; 111 case PIPE_LOGICOP_COPY_INVERTED: 112 blend->rt[i].blend_enable = TRUE; 113 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 114 blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; 115 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; 116 break; 117 case PIPE_LOGICOP_NOOP: 118 blend->rt[i].blend_enable = TRUE; 119 blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO; 120 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 121 blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; 122 break; 123 case PIPE_LOGICOP_SET: 124 blend->rt[i].blend_enable = TRUE; 125 blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; 126 blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE; 127 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 128 break; 129 case PIPE_LOGICOP_AND: 130 /* Approximate with minimum - works for the 0 & anything case: */ 131 blend->rt[i].blend_enable = TRUE; 132 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 133 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 134 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; 135 break; 136 case PIPE_LOGICOP_AND_REVERSE: 137 blend->rt[i].blend_enable = TRUE; 138 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 139 blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; 140 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; 141 break; 142 case PIPE_LOGICOP_AND_INVERTED: 143 blend->rt[i].blend_enable = TRUE; 144 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 145 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 146 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; 147 break; 148 case PIPE_LOGICOP_OR: 149 /* Approximate with maximum - works for the 1 | anything case: */ 150 blend->rt[i].blend_enable = TRUE; 151 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 152 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 153 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 154 break; 155 case PIPE_LOGICOP_OR_REVERSE: 156 blend->rt[i].blend_enable = TRUE; 157 blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 158 blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; 159 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 160 break; 161 case PIPE_LOGICOP_OR_INVERTED: 162 blend->rt[i].blend_enable = TRUE; 163 blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 164 blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 165 blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 166 break; 167 case PIPE_LOGICOP_NAND: 168 case PIPE_LOGICOP_NOR: 169 case PIPE_LOGICOP_EQUIV: 170 /* Fill these in with plausible values */ 171 blend->rt[i].blend_enable = FALSE; 172 break; 173 default: 174 assert(0); 175 break; 176 } 177 } 178 else { 179 blend->rt[i].blend_enable = templ->rt[0].blend_enable; 180 181 if (templ->rt[0].blend_enable) { 182 blend->rt[i].srcblend = svga_translate_blend_factor(templ->rt[0].rgb_src_factor); 183 blend->rt[i].dstblend = svga_translate_blend_factor(templ->rt[0].rgb_dst_factor); 184 blend->rt[i].blendeq = svga_translate_blend_func(templ->rt[0].rgb_func); 185 blend->rt[i].srcblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_src_factor); 186 blend->rt[i].dstblend_alpha = svga_translate_blend_factor(templ->rt[0].alpha_dst_factor); 187 blend->rt[i].blendeq_alpha = svga_translate_blend_func(templ->rt[0].alpha_func); 188 189 if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend || 190 blend->rt[i].dstblend_alpha != blend->rt[i].dstblend || 191 blend->rt[i].blendeq_alpha != blend->rt[i].blendeq) 192 { 193 blend->rt[i].separate_alpha_blend_enable = TRUE; 194 } 195 } 196 } 197 198 blend->rt[i].writemask = templ->rt[0].colormask; 199 } 200 201 return blend; 202 } 203 204 static void svga_bind_blend_state(struct pipe_context *pipe, 205 void *blend) 206 { 207 struct svga_context *svga = svga_context(pipe); 208 209 svga->curr.blend = (struct svga_blend_state*)blend; 210 svga->dirty |= SVGA_NEW_BLEND; 211 } 212 213 214 static void svga_delete_blend_state(struct pipe_context *pipe, void *blend) 215 { 216 FREE(blend); 217 } 218 219 static void svga_set_blend_color( struct pipe_context *pipe, 220 const struct pipe_blend_color *blend_color ) 221 { 222 struct svga_context *svga = svga_context(pipe); 223 224 svga->curr.blend_color = *blend_color; 225 226 svga->dirty |= SVGA_NEW_BLEND_COLOR; 227 } 228 229 230 void svga_init_blend_functions( struct svga_context *svga ) 231 { 232 svga->pipe.create_blend_state = svga_create_blend_state; 233 svga->pipe.bind_blend_state = svga_bind_blend_state; 234 svga->pipe.delete_blend_state = svga_delete_blend_state; 235 236 svga->pipe.set_blend_color = svga_set_blend_color; 237 } 238 239 240 241