Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 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 | |
José Fonseca | 2848688 | 2010-02-02 14:42:17 +0000 | [diff] [blame] | 26 | #include "util/u_inlines.h" |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 27 | #include "pipe/p_defines.h" |
| 28 | #include "util/u_math.h" |
| 29 | #include "util/u_memory.h" |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 30 | #include "util/u_bitmask.h" |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 31 | |
| 32 | #include "svga_context.h" |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 33 | #include "svga_hw_reg.h" |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 34 | #include "svga_cmd.h" |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 35 | |
| 36 | |
Ilia Mirkin | a2a1a58 | 2015-07-20 19:58:43 -0400 | [diff] [blame] | 37 | static inline unsigned |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 38 | svga_translate_blend_factor(const struct svga_context *svga, unsigned factor) |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 39 | { |
Brian Paul | 93779b8 | 2016-08-19 09:36:02 -0600 | [diff] [blame] | 40 | /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so |
| 41 | * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly. |
| 42 | */ |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 43 | switch (factor) { |
| 44 | case PIPE_BLENDFACTOR_ZERO: return SVGA3D_BLENDOP_ZERO; |
| 45 | case PIPE_BLENDFACTOR_SRC_ALPHA: return SVGA3D_BLENDOP_SRCALPHA; |
| 46 | case PIPE_BLENDFACTOR_ONE: return SVGA3D_BLENDOP_ONE; |
| 47 | case PIPE_BLENDFACTOR_SRC_COLOR: return SVGA3D_BLENDOP_SRCCOLOR; |
| 48 | case PIPE_BLENDFACTOR_INV_SRC_COLOR: return SVGA3D_BLENDOP_INVSRCCOLOR; |
| 49 | case PIPE_BLENDFACTOR_DST_COLOR: return SVGA3D_BLENDOP_DESTCOLOR; |
| 50 | case PIPE_BLENDFACTOR_INV_DST_COLOR: return SVGA3D_BLENDOP_INVDESTCOLOR; |
| 51 | case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return SVGA3D_BLENDOP_INVSRCALPHA; |
| 52 | case PIPE_BLENDFACTOR_DST_ALPHA: return SVGA3D_BLENDOP_DESTALPHA; |
| 53 | case PIPE_BLENDFACTOR_INV_DST_ALPHA: return SVGA3D_BLENDOP_INVDESTALPHA; |
| 54 | case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT; |
| 55 | case PIPE_BLENDFACTOR_CONST_COLOR: return SVGA3D_BLENDOP_BLENDFACTOR; |
| 56 | case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR; |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 57 | case PIPE_BLENDFACTOR_CONST_ALPHA: |
| 58 | if (svga_have_vgpu10(svga)) |
| 59 | return SVGA3D_BLENDOP_BLENDFACTORALPHA; |
| 60 | else |
| 61 | return SVGA3D_BLENDOP_BLENDFACTOR; /* as close as we can get */ |
| 62 | case PIPE_BLENDFACTOR_INV_CONST_ALPHA: |
| 63 | if (svga_have_vgpu10(svga)) |
| 64 | return SVGA3D_BLENDOP_INVBLENDFACTORALPHA; |
| 65 | else |
| 66 | return SVGA3D_BLENDOP_INVBLENDFACTOR; /* as close as we can get */ |
| 67 | case PIPE_BLENDFACTOR_SRC1_COLOR: return SVGA3D_BLENDOP_SRC1COLOR; |
| 68 | case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return SVGA3D_BLENDOP_INVSRC1COLOR; |
| 69 | case PIPE_BLENDFACTOR_SRC1_ALPHA: return SVGA3D_BLENDOP_SRC1ALPHA; |
| 70 | case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return SVGA3D_BLENDOP_INVSRC1ALPHA; |
| 71 | case 0: return SVGA3D_BLENDOP_ONE; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 72 | default: |
| 73 | assert(0); |
| 74 | return SVGA3D_BLENDOP_ZERO; |
| 75 | } |
| 76 | } |
| 77 | |
Ilia Mirkin | a2a1a58 | 2015-07-20 19:58:43 -0400 | [diff] [blame] | 78 | static inline unsigned |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 79 | svga_translate_blend_func(unsigned mode) |
| 80 | { |
| 81 | switch (mode) { |
| 82 | case PIPE_BLEND_ADD: return SVGA3D_BLENDEQ_ADD; |
| 83 | case PIPE_BLEND_SUBTRACT: return SVGA3D_BLENDEQ_SUBTRACT; |
| 84 | case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT; |
| 85 | case PIPE_BLEND_MIN: return SVGA3D_BLENDEQ_MINIMUM; |
| 86 | case PIPE_BLEND_MAX: return SVGA3D_BLENDEQ_MAXIMUM; |
| 87 | default: |
| 88 | assert(0); |
| 89 | return SVGA3D_BLENDEQ_ADD; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 94 | /** |
| 95 | * Define a vgpu10 blend state object for the given |
| 96 | * svga blend state. |
| 97 | */ |
| 98 | static void |
| 99 | define_blend_state_object(struct svga_context *svga, |
| 100 | struct svga_blend_state *bs) |
| 101 | { |
| 102 | SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS]; |
| 103 | unsigned try; |
| 104 | int i; |
| 105 | |
| 106 | assert(svga_have_vgpu10(svga)); |
| 107 | |
| 108 | bs->id = util_bitmask_add(svga->blend_object_id_bm); |
| 109 | |
| 110 | for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) { |
| 111 | perRT[i].blendEnable = bs->rt[i].blend_enable; |
| 112 | perRT[i].srcBlend = bs->rt[i].srcblend; |
| 113 | perRT[i].destBlend = bs->rt[i].dstblend; |
| 114 | perRT[i].blendOp = bs->rt[i].blendeq; |
| 115 | perRT[i].srcBlendAlpha = bs->rt[i].srcblend_alpha; |
| 116 | perRT[i].destBlendAlpha = bs->rt[i].dstblend_alpha; |
| 117 | perRT[i].blendOpAlpha = bs->rt[i].blendeq_alpha; |
| 118 | perRT[i].renderTargetWriteMask = bs->rt[i].writemask; |
| 119 | perRT[i].logicOpEnable = 0; |
| 120 | perRT[i].logicOp = SVGA3D_LOGICOP_COPY; |
| 121 | assert(perRT[i].srcBlend == perRT[0].srcBlend); |
| 122 | } |
| 123 | |
| 124 | /* Loop in case command buffer is full and we need to flush and retry */ |
| 125 | for (try = 0; try < 2; try++) { |
| 126 | enum pipe_error ret; |
| 127 | |
| 128 | ret = SVGA3D_vgpu10_DefineBlendState(svga->swc, |
| 129 | bs->id, |
| 130 | bs->alpha_to_coverage, |
| 131 | bs->independent_blend_enable, |
| 132 | perRT); |
| 133 | if (ret == PIPE_OK) |
| 134 | return; |
| 135 | svga_context_flush(svga, NULL); |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 140 | static void * |
| 141 | svga_create_blend_state(struct pipe_context *pipe, |
| 142 | const struct pipe_blend_state *templ) |
| 143 | { |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 144 | struct svga_context *svga = svga_context(pipe); |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 145 | struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state ); |
| 146 | unsigned i; |
| 147 | |
Brian Paul | 9f443af | 2016-04-05 09:56:49 -0600 | [diff] [blame] | 148 | if (!blend) |
| 149 | return NULL; |
| 150 | |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 151 | /* Fill in the per-rendertarget blend state. We currently only |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 152 | * support independent blend enable and colormask per render target. |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 153 | */ |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 154 | for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 155 | /* No way to set this in SVGA3D, and no way to correctly implement it on |
| 156 | * top of D3D9 API. Instead we try to simulate with various blend modes. |
| 157 | */ |
| 158 | if (templ->logicop_enable) { |
| 159 | switch (templ->logicop_func) { |
| 160 | case PIPE_LOGICOP_XOR: |
José Fonseca | 12d5203 | 2010-01-27 14:45:56 +0000 | [diff] [blame] | 161 | case PIPE_LOGICOP_INVERT: |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 162 | blend->need_white_fragments = TRUE; |
| 163 | blend->rt[i].blend_enable = TRUE; |
| 164 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; |
| 165 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE; |
| 166 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_SUBTRACT; |
| 167 | break; |
| 168 | case PIPE_LOGICOP_CLEAR: |
| 169 | blend->rt[i].blend_enable = TRUE; |
| 170 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO; |
| 171 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; |
| 172 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; |
| 173 | break; |
| 174 | case PIPE_LOGICOP_COPY: |
| 175 | blend->rt[i].blend_enable = FALSE; |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 176 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; |
| 177 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; |
| 178 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 179 | break; |
| 180 | case PIPE_LOGICOP_COPY_INVERTED: |
| 181 | blend->rt[i].blend_enable = TRUE; |
| 182 | blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; |
| 183 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; |
| 184 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; |
| 185 | break; |
| 186 | case PIPE_LOGICOP_NOOP: |
| 187 | blend->rt[i].blend_enable = TRUE; |
| 188 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO; |
| 189 | blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; |
| 190 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; |
| 191 | break; |
| 192 | case PIPE_LOGICOP_SET: |
| 193 | blend->rt[i].blend_enable = TRUE; |
| 194 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; |
| 195 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE; |
| 196 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; |
| 197 | break; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 198 | case PIPE_LOGICOP_AND: |
| 199 | /* Approximate with minimum - works for the 0 & anything case: */ |
| 200 | blend->rt[i].blend_enable = TRUE; |
| 201 | blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; |
| 202 | blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; |
| 203 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; |
| 204 | break; |
| 205 | case PIPE_LOGICOP_AND_REVERSE: |
| 206 | blend->rt[i].blend_enable = TRUE; |
| 207 | blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; |
| 208 | blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; |
| 209 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; |
| 210 | break; |
| 211 | case PIPE_LOGICOP_AND_INVERTED: |
| 212 | blend->rt[i].blend_enable = TRUE; |
| 213 | blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; |
| 214 | blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; |
| 215 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MINIMUM; |
| 216 | break; |
| 217 | case PIPE_LOGICOP_OR: |
| 218 | /* Approximate with maximum - works for the 1 | anything case: */ |
| 219 | blend->rt[i].blend_enable = TRUE; |
| 220 | blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; |
| 221 | blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; |
| 222 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; |
| 223 | break; |
| 224 | case PIPE_LOGICOP_OR_REVERSE: |
| 225 | blend->rt[i].blend_enable = TRUE; |
| 226 | blend->rt[i].srcblend = SVGA3D_BLENDOP_SRCCOLOR; |
| 227 | blend->rt[i].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; |
| 228 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; |
| 229 | break; |
| 230 | case PIPE_LOGICOP_OR_INVERTED: |
| 231 | blend->rt[i].blend_enable = TRUE; |
| 232 | blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; |
| 233 | blend->rt[i].dstblend = SVGA3D_BLENDOP_DESTCOLOR; |
| 234 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM; |
| 235 | break; |
| 236 | case PIPE_LOGICOP_NAND: |
| 237 | case PIPE_LOGICOP_NOR: |
| 238 | case PIPE_LOGICOP_EQUIV: |
| 239 | /* Fill these in with plausible values */ |
| 240 | blend->rt[i].blend_enable = FALSE; |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 241 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; |
| 242 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; |
| 243 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 244 | break; |
| 245 | default: |
| 246 | assert(0); |
| 247 | break; |
| 248 | } |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 249 | blend->rt[i].srcblend_alpha = blend->rt[i].srcblend; |
| 250 | blend->rt[i].dstblend_alpha = blend->rt[i].dstblend; |
| 251 | blend->rt[i].blendeq_alpha = blend->rt[i].blendeq; |
Brian Paul | 32a6e08 | 2015-12-04 12:26:35 -0700 | [diff] [blame] | 252 | |
| 253 | if (templ->logicop_func == PIPE_LOGICOP_XOR) { |
| 254 | pipe_debug_message(&svga->debug.callback, CONFORMANCE, |
| 255 | "XOR logicop mode has limited support"); |
| 256 | } |
| 257 | else if (templ->logicop_func != PIPE_LOGICOP_COPY) { |
| 258 | pipe_debug_message(&svga->debug.callback, CONFORMANCE, |
| 259 | "general logicops are not supported"); |
| 260 | } |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 261 | } |
| 262 | else { |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 263 | /* Note: the vgpu10 device does not yet support independent |
| 264 | * blend terms per render target. Target[0] always specifies the |
| 265 | * blending terms. |
| 266 | */ |
| 267 | if (templ->independent_blend_enable || templ->rt[0].blend_enable) { |
| 268 | /* always use the 0th target's blending terms for now */ |
| 269 | blend->rt[i].srcblend = |
| 270 | svga_translate_blend_factor(svga, templ->rt[0].rgb_src_factor); |
| 271 | blend->rt[i].dstblend = |
| 272 | svga_translate_blend_factor(svga, templ->rt[0].rgb_dst_factor); |
| 273 | blend->rt[i].blendeq = |
| 274 | svga_translate_blend_func(templ->rt[0].rgb_func); |
| 275 | blend->rt[i].srcblend_alpha = |
| 276 | svga_translate_blend_factor(svga, templ->rt[0].alpha_src_factor); |
| 277 | blend->rt[i].dstblend_alpha = |
| 278 | svga_translate_blend_factor(svga, templ->rt[0].alpha_dst_factor); |
| 279 | blend->rt[i].blendeq_alpha = |
| 280 | svga_translate_blend_func(templ->rt[0].alpha_func); |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 281 | |
| 282 | if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend || |
| 283 | blend->rt[i].dstblend_alpha != blend->rt[i].dstblend || |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 284 | blend->rt[i].blendeq_alpha != blend->rt[i].blendeq) { |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 285 | blend->rt[i].separate_alpha_blend_enable = TRUE; |
| 286 | } |
| 287 | } |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 288 | else { |
| 289 | /* disabled - default blend terms */ |
| 290 | blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; |
| 291 | blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; |
| 292 | blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; |
| 293 | blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ONE; |
| 294 | blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO; |
| 295 | blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD; |
| 296 | } |
| 297 | |
| 298 | if (templ->independent_blend_enable) { |
| 299 | blend->rt[i].blend_enable = templ->rt[i].blend_enable; |
| 300 | } |
| 301 | else { |
| 302 | blend->rt[i].blend_enable = templ->rt[0].blend_enable; |
| 303 | } |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 304 | } |
| 305 | |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 306 | /* Some GL blend modes are not supported by the VGPU9 device (there's |
| 307 | * no equivalent of PIPE_BLENDFACTOR_[INV_]CONST_ALPHA). |
| 308 | * When we set this flag, we copy the constant blend alpha value |
| 309 | * to the R, G, B components. |
| 310 | * This works as long as the src/dst RGB blend factors doesn't use |
| 311 | * PIPE_BLENDFACTOR_CONST_COLOR and PIPE_BLENDFACTOR_CONST_ALPHA |
| 312 | * at the same time. There's no work-around for that. |
| 313 | */ |
| 314 | if (!svga_have_vgpu10(svga)) { |
| 315 | if (templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_CONST_ALPHA || |
| 316 | templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_CONST_ALPHA || |
| 317 | templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA || |
| 318 | templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA) { |
| 319 | blend->blend_color_alpha = TRUE; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | if (templ->independent_blend_enable) { |
| 324 | blend->rt[i].writemask = templ->rt[i].colormask; |
| 325 | } |
| 326 | else { |
| 327 | blend->rt[i].writemask = templ->rt[0].colormask; |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | blend->independent_blend_enable = templ->independent_blend_enable; |
| 332 | |
| 333 | blend->alpha_to_coverage = templ->alpha_to_coverage; |
Brian Paul | 91735e2d | 2017-07-21 10:37:36 -0600 | [diff] [blame] | 334 | blend->alpha_to_one = templ->alpha_to_one; |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 335 | |
| 336 | if (svga_have_vgpu10(svga)) { |
| 337 | define_blend_state_object(svga, blend); |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 338 | } |
| 339 | |
Brian Paul | 464d608 | 2016-04-15 15:30:34 -0600 | [diff] [blame] | 340 | svga->hud.num_blend_objects++; |
Charmaine Lee | 2e1cfcc | 2016-08-19 08:49:17 -0600 | [diff] [blame] | 341 | SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, |
| 342 | SVGA_STATS_COUNT_BLENDSTATE); |
Neha Bhende | 9bc7e31 | 2015-10-09 16:10:16 -0600 | [diff] [blame] | 343 | |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 344 | return blend; |
| 345 | } |
| 346 | |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 347 | |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 348 | static void svga_bind_blend_state(struct pipe_context *pipe, |
| 349 | void *blend) |
| 350 | { |
| 351 | struct svga_context *svga = svga_context(pipe); |
| 352 | |
| 353 | svga->curr.blend = (struct svga_blend_state*)blend; |
| 354 | svga->dirty |= SVGA_NEW_BLEND; |
| 355 | } |
| 356 | |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 357 | static void svga_delete_blend_state(struct pipe_context *pipe, |
| 358 | void *blend) |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 359 | { |
Brian Paul | e054251 | 2015-08-13 11:00:58 -0700 | [diff] [blame] | 360 | struct svga_context *svga = svga_context(pipe); |
| 361 | struct svga_blend_state *bs = |
| 362 | (struct svga_blend_state *) blend; |
| 363 | |
| 364 | if (bs->id != SVGA3D_INVALID_ID) { |
| 365 | enum pipe_error ret; |
| 366 | |
| 367 | ret = SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id); |
| 368 | if (ret != PIPE_OK) { |
| 369 | svga_context_flush(svga, NULL); |
| 370 | ret = SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id); |
| 371 | assert(ret == PIPE_OK); |
| 372 | } |
| 373 | |
| 374 | if (bs->id == svga->state.hw_draw.blend_id) |
| 375 | svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID; |
| 376 | |
| 377 | util_bitmask_clear(svga->blend_object_id_bm, bs->id); |
| 378 | bs->id = SVGA3D_INVALID_ID; |
| 379 | } |
| 380 | |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 381 | FREE(blend); |
Brian Paul | 464d608 | 2016-04-15 15:30:34 -0600 | [diff] [blame] | 382 | svga->hud.num_blend_objects--; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 383 | } |
| 384 | |
| 385 | static void svga_set_blend_color( struct pipe_context *pipe, |
| 386 | const struct pipe_blend_color *blend_color ) |
| 387 | { |
| 388 | struct svga_context *svga = svga_context(pipe); |
| 389 | |
| 390 | svga->curr.blend_color = *blend_color; |
| 391 | |
José Fonseca | cd5d760 | 2010-02-12 23:17:04 +0000 | [diff] [blame] | 392 | svga->dirty |= SVGA_NEW_BLEND_COLOR; |
Jakob Bornecrantz | 3192633 | 2009-11-16 19:56:18 +0100 | [diff] [blame] | 393 | } |
| 394 | |
| 395 | |
| 396 | void svga_init_blend_functions( struct svga_context *svga ) |
| 397 | { |
| 398 | svga->pipe.create_blend_state = svga_create_blend_state; |
| 399 | svga->pipe.bind_blend_state = svga_bind_blend_state; |
| 400 | svga->pipe.delete_blend_state = svga_delete_blend_state; |
| 401 | |
| 402 | svga->pipe.set_blend_color = svga_set_blend_color; |
| 403 | } |