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 #include "util/u_bitmask.h"
31 
32 #include "svga_context.h"
33 #include "svga_hw_reg.h"
34 #include "svga_cmd.h"
35 
36 
37 static inline unsigned
svga_translate_blend_factor(const struct svga_context * svga,unsigned factor)38 svga_translate_blend_factor(const struct svga_context *svga, unsigned factor)
39 {
40    /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so
41     * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly.
42     */
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;
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;
72    default:
73       assert(0);
74       return SVGA3D_BLENDOP_ZERO;
75    }
76 }
77 
78 static inline unsigned
svga_translate_blend_func(unsigned mode)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 
94 /**
95  * Translate gallium logicop mode to SVGA3D logicop mode.
96  */
97 static int
translate_logicop(enum pipe_logicop op)98 translate_logicop(enum pipe_logicop op)
99 {
100    switch (op) {
101    case PIPE_LOGICOP_CLEAR:
102       return SVGA3D_DX11_LOGICOP_CLEAR;
103    case PIPE_LOGICOP_NOR:
104       return SVGA3D_DX11_LOGICOP_NOR;
105    case PIPE_LOGICOP_AND_INVERTED:
106       return SVGA3D_DX11_LOGICOP_AND_INVERTED;
107    case PIPE_LOGICOP_COPY_INVERTED:
108       return SVGA3D_DX11_LOGICOP_COPY_INVERTED;
109    case PIPE_LOGICOP_AND_REVERSE:
110       return SVGA3D_DX11_LOGICOP_AND_REVERSE;
111    case PIPE_LOGICOP_INVERT:
112       return SVGA3D_DX11_LOGICOP_INVERT;
113    case PIPE_LOGICOP_XOR:
114       return SVGA3D_DX11_LOGICOP_XOR;
115    case PIPE_LOGICOP_NAND:
116       return SVGA3D_DX11_LOGICOP_NAND;
117    case PIPE_LOGICOP_AND:
118       return SVGA3D_DX11_LOGICOP_AND;
119    case PIPE_LOGICOP_EQUIV:
120       return SVGA3D_DX11_LOGICOP_EQUIV;
121    case PIPE_LOGICOP_NOOP:
122       return SVGA3D_DX11_LOGICOP_NOOP;
123    case PIPE_LOGICOP_OR_INVERTED:
124       return SVGA3D_DX11_LOGICOP_OR_INVERTED;
125    case PIPE_LOGICOP_COPY:
126       return SVGA3D_DX11_LOGICOP_COPY;
127    case PIPE_LOGICOP_OR_REVERSE:
128       return SVGA3D_DX11_LOGICOP_OR_REVERSE;
129    case PIPE_LOGICOP_OR:
130       return SVGA3D_DX11_LOGICOP_OR;
131    case PIPE_LOGICOP_SET:
132       return SVGA3D_DX11_LOGICOP_SET;
133    default:
134       return SVGA3D_DX11_LOGICOP_COPY;
135    }
136 };
137 
138 
139 /**
140  * Define a vgpu10 blend state object for the given
141  * svga blend state.
142  */
143 static void
define_blend_state_object(struct svga_context * svga,struct svga_blend_state * bs)144 define_blend_state_object(struct svga_context *svga,
145                           struct svga_blend_state *bs)
146 {
147    SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
148    int i;
149 
150    assert(svga_have_vgpu10(svga));
151 
152    bs->id = util_bitmask_add(svga->blend_object_id_bm);
153 
154    for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) {
155       perRT[i].blendEnable = bs->rt[i].blend_enable;
156       perRT[i].srcBlend = bs->rt[i].srcblend;
157       perRT[i].destBlend = bs->rt[i].dstblend;
158       perRT[i].blendOp = bs->rt[i].blendeq;
159       perRT[i].srcBlendAlpha = bs->rt[i].srcblend_alpha;
160       perRT[i].destBlendAlpha = bs->rt[i].dstblend_alpha;
161       perRT[i].blendOpAlpha = bs->rt[i].blendeq_alpha;
162       perRT[i].renderTargetWriteMask = bs->rt[i].writemask;
163       perRT[i].logicOpEnable = bs->logicop_enabled;
164       perRT[i].logicOp = bs->logicop_mode;
165    }
166 
167    SVGA_RETRY(svga, SVGA3D_vgpu10_DefineBlendState(svga->swc,
168                                                    bs->id,
169                                                    bs->alpha_to_coverage,
170                                                    bs->independent_blend_enable,
171                                                    perRT));
172 }
173 
174 
175 /**
176  * If SVGA3D_DEVCAP_LOGIC_BLENDOPS is false, we can't directly implement
177  * GL's logicops.  But we can emulate some of them.  We set up the blending
178  * state for that here.
179  */
180 static void
emulate_logicop(struct svga_context * svga,unsigned logicop_func,struct svga_blend_state * blend,unsigned buffer)181 emulate_logicop(struct svga_context *svga,
182                 unsigned logicop_func,
183                 struct svga_blend_state *blend,
184                 unsigned buffer)
185 {
186    switch (logicop_func) {
187    case PIPE_LOGICOP_XOR:
188    case PIPE_LOGICOP_INVERT:
189       blend->need_white_fragments = TRUE;
190       blend->rt[buffer].blend_enable = TRUE;
191       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
192       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ONE;
193       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_SUBTRACT;
194       break;
195    case PIPE_LOGICOP_CLEAR:
196       blend->rt[buffer].blend_enable = TRUE;
197       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ZERO;
198       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
199       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
200       break;
201    case PIPE_LOGICOP_COPY:
202       blend->rt[buffer].blend_enable = FALSE;
203       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
204       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
205       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
206       break;
207    case PIPE_LOGICOP_COPY_INVERTED:
208       blend->rt[buffer].blend_enable   = TRUE;
209       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
210       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
211       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
212       break;
213    case PIPE_LOGICOP_NOOP:
214       blend->rt[buffer].blend_enable   = TRUE;
215       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ZERO;
216       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
217       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
218       break;
219    case PIPE_LOGICOP_SET:
220       blend->rt[buffer].blend_enable = TRUE;
221       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
222       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ONE;
223       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
224       break;
225    case PIPE_LOGICOP_AND:
226       /* Approximate with minimum - works for the 0 & anything case: */
227       blend->rt[buffer].blend_enable = TRUE;
228       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
229       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
230       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
231       break;
232    case PIPE_LOGICOP_AND_REVERSE:
233       blend->rt[buffer].blend_enable = TRUE;
234       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
235       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
236       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
237       break;
238    case PIPE_LOGICOP_AND_INVERTED:
239       blend->rt[buffer].blend_enable = TRUE;
240       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
241       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
242       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
243       break;
244    case PIPE_LOGICOP_OR:
245       /* Approximate with maximum - works for the 1 | anything case: */
246       blend->rt[buffer].blend_enable = TRUE;
247       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
248       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
249       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
250       break;
251    case PIPE_LOGICOP_OR_REVERSE:
252       blend->rt[buffer].blend_enable = TRUE;
253       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
254       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
255       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
256       break;
257    case PIPE_LOGICOP_OR_INVERTED:
258       blend->rt[buffer].blend_enable = TRUE;
259       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
260       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
261       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
262       break;
263    case PIPE_LOGICOP_NAND:
264    case PIPE_LOGICOP_NOR:
265    case PIPE_LOGICOP_EQUIV:
266       /* Fill these in with plausible values */
267       blend->rt[buffer].blend_enable = FALSE;
268       blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
269       blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
270       blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
271       break;
272    default:
273       assert(0);
274       break;
275    }
276    blend->rt[buffer].srcblend_alpha = blend->rt[buffer].srcblend;
277    blend->rt[buffer].dstblend_alpha = blend->rt[buffer].dstblend;
278    blend->rt[buffer].blendeq_alpha = blend->rt[buffer].blendeq;
279 
280    if (logicop_func == PIPE_LOGICOP_XOR) {
281       pipe_debug_message(&svga->debug.callback, CONFORMANCE,
282                          "XOR logicop mode has limited support");
283    }
284    else if (logicop_func != PIPE_LOGICOP_COPY) {
285       pipe_debug_message(&svga->debug.callback, CONFORMANCE,
286                          "general logicops are not supported");
287    }
288 }
289 
290 
291 
292 static void *
svga_create_blend_state(struct pipe_context * pipe,const struct pipe_blend_state * templ)293 svga_create_blend_state(struct pipe_context *pipe,
294                         const struct pipe_blend_state *templ)
295 {
296    struct svga_context *svga = svga_context(pipe);
297    struct svga_screen *ss = svga_screen(pipe->screen);
298    struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
299    unsigned i;
300 
301    if (!blend)
302       return NULL;
303 
304    /* Find index of first target with blending enabled.  If no blending is
305     * enabled at all, first_enabled will be zero.
306     */
307    unsigned first_enabled = 0;
308    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
309       if (templ->rt[i].blend_enable) {
310          first_enabled = i;
311          break;
312       }
313    }
314 
315    /* Fill in the per-rendertarget blend state.  We currently only
316     * support independent blend enable and colormask per render target.
317     */
318    for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
319       /* No way to set this in SVGA3D, and no way to correctly implement it on
320        * top of D3D9 API.  Instead we try to simulate with various blend modes.
321        */
322       if (templ->logicop_enable) {
323          if (ss->haveBlendLogicops) {
324             blend->logicop_enabled = TRUE;
325             blend->logicop_mode = translate_logicop(templ->logicop_func);
326             blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
327             blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD;
328             blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
329             blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
330             blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ZERO;
331             blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO;
332          }
333          else {
334             emulate_logicop(svga, templ->logicop_func, blend, i);
335          }
336       }
337       else {
338          /* Note: per-target blend terms are only supported for sm4_1
339           * device. For vgpu10 device, the blending terms must be identical
340           * for all targets (this is why we need the first_enabled index).
341           */
342          const unsigned j =
343             svga_have_sm4_1(svga) && templ->independent_blend_enable
344             ? i : first_enabled;
345          if (templ->independent_blend_enable || templ->rt[j].blend_enable) {
346             blend->rt[i].srcblend =
347                svga_translate_blend_factor(svga, templ->rt[j].rgb_src_factor);
348             blend->rt[i].dstblend =
349                svga_translate_blend_factor(svga, templ->rt[j].rgb_dst_factor);
350             blend->rt[i].blendeq =
351                svga_translate_blend_func(templ->rt[j].rgb_func);
352             blend->rt[i].srcblend_alpha =
353                svga_translate_blend_factor(svga, templ->rt[j].alpha_src_factor);
354             blend->rt[i].dstblend_alpha =
355                svga_translate_blend_factor(svga, templ->rt[j].alpha_dst_factor);
356             blend->rt[i].blendeq_alpha =
357                svga_translate_blend_func(templ->rt[j].alpha_func);
358 
359             if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
360                 blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
361                 blend->rt[i].blendeq_alpha  != blend->rt[i].blendeq) {
362                blend->rt[i].separate_alpha_blend_enable = TRUE;
363             }
364          }
365          else {
366             /* disabled - default blend terms */
367             blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
368             blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
369             blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
370             blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ONE;
371             blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO;
372             blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD;
373          }
374 
375          if (templ->independent_blend_enable) {
376             blend->rt[i].blend_enable = templ->rt[i].blend_enable;
377          }
378          else {
379             blend->rt[i].blend_enable = templ->rt[0].blend_enable;
380          }
381       }
382 
383       /* Some GL blend modes are not supported by the VGPU9 device (there's
384        * no equivalent of PIPE_BLENDFACTOR_[INV_]CONST_ALPHA).
385        * When we set this flag, we copy the constant blend alpha value
386        * to the R, G, B components.
387        * This works as long as the src/dst RGB blend factors doesn't use
388        * PIPE_BLENDFACTOR_CONST_COLOR and PIPE_BLENDFACTOR_CONST_ALPHA
389        * at the same time.  There's no work-around for that.
390        */
391       if (!svga_have_vgpu10(svga)) {
392          if (templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
393              templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
394              templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA ||
395              templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA) {
396             blend->blend_color_alpha = TRUE;
397          }
398       }
399 
400       if (templ->independent_blend_enable) {
401          blend->rt[i].writemask = templ->rt[i].colormask;
402       }
403       else {
404          blend->rt[i].writemask = templ->rt[0].colormask;
405       }
406    }
407 
408    blend->independent_blend_enable = templ->independent_blend_enable;
409 
410    blend->alpha_to_coverage = templ->alpha_to_coverage;
411    blend->alpha_to_one = templ->alpha_to_one;
412 
413    if (svga_have_vgpu10(svga)) {
414       define_blend_state_object(svga, blend);
415    }
416 
417    svga->hud.num_blend_objects++;
418    SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
419                         SVGA_STATS_COUNT_BLENDSTATE);
420 
421    return blend;
422 }
423 
424 
svga_bind_blend_state(struct pipe_context * pipe,void * blend)425 static void svga_bind_blend_state(struct pipe_context *pipe,
426                                   void *blend)
427 {
428    struct svga_context *svga = svga_context(pipe);
429 
430    svga->curr.blend = (struct svga_blend_state*)blend;
431    svga->dirty |= SVGA_NEW_BLEND;
432 }
433 
svga_delete_blend_state(struct pipe_context * pipe,void * blend)434 static void svga_delete_blend_state(struct pipe_context *pipe,
435                                     void *blend)
436 {
437    struct svga_context *svga = svga_context(pipe);
438    struct svga_blend_state *bs =
439       (struct svga_blend_state *) blend;
440 
441    if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) {
442       SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id));
443 
444       if (bs->id == svga->state.hw_draw.blend_id)
445          svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID;
446 
447       util_bitmask_clear(svga->blend_object_id_bm, bs->id);
448       bs->id = SVGA3D_INVALID_ID;
449    }
450 
451    FREE(blend);
452    svga->hud.num_blend_objects--;
453 }
454 
svga_set_blend_color(struct pipe_context * pipe,const struct pipe_blend_color * blend_color)455 static void svga_set_blend_color( struct pipe_context *pipe,
456                                   const struct pipe_blend_color *blend_color )
457 {
458    struct svga_context *svga = svga_context(pipe);
459 
460    svga->curr.blend_color = *blend_color;
461 
462    svga->dirty |= SVGA_NEW_BLEND_COLOR;
463 }
464 
465 
svga_init_blend_functions(struct svga_context * svga)466 void svga_init_blend_functions( struct svga_context *svga )
467 {
468    svga->pipe.create_blend_state = svga_create_blend_state;
469    svga->pipe.bind_blend_state = svga_bind_blend_state;
470    svga->pipe.delete_blend_state = svga_delete_blend_state;
471 
472    svga->pipe.set_blend_color = svga_set_blend_color;
473 }
474