1bf215546Sopenharmony_ci/**********************************************************
2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc.  All rights reserved.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person
5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation
6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without
7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy,
8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies
9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is
10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be
13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22bf215546Sopenharmony_ci * SOFTWARE.
23bf215546Sopenharmony_ci *
24bf215546Sopenharmony_ci **********************************************************/
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "util/u_inlines.h"
27bf215546Sopenharmony_ci#include "pipe/p_defines.h"
28bf215546Sopenharmony_ci#include "util/u_math.h"
29bf215546Sopenharmony_ci#include "util/u_memory.h"
30bf215546Sopenharmony_ci#include "util/u_bitmask.h"
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "svga_context.h"
33bf215546Sopenharmony_ci#include "svga_hw_reg.h"
34bf215546Sopenharmony_ci#include "svga_cmd.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_cistatic inline unsigned
38bf215546Sopenharmony_cisvga_translate_blend_factor(const struct svga_context *svga, unsigned factor)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so
41bf215546Sopenharmony_ci    * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly.
42bf215546Sopenharmony_ci    */
43bf215546Sopenharmony_ci   switch (factor) {
44bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ZERO:            return SVGA3D_BLENDOP_ZERO;
45bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA:       return SVGA3D_BLENDOP_SRCALPHA;
46bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_ONE:             return SVGA3D_BLENDOP_ONE;
47bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_COLOR:       return SVGA3D_BLENDOP_SRCCOLOR;
48bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_COLOR:   return SVGA3D_BLENDOP_INVSRCCOLOR;
49bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_COLOR:       return SVGA3D_BLENDOP_DESTCOLOR;
50bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_COLOR:   return SVGA3D_BLENDOP_INVDESTCOLOR;
51bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC_ALPHA:   return SVGA3D_BLENDOP_INVSRCALPHA;
52bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_DST_ALPHA:       return SVGA3D_BLENDOP_DESTALPHA;
53bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_DST_ALPHA:   return SVGA3D_BLENDOP_INVDESTALPHA;
54bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT;
55bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_COLOR:     return SVGA3D_BLENDOP_BLENDFACTOR;
56bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR;
57bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_CONST_ALPHA:
58bf215546Sopenharmony_ci      if (svga_have_vgpu10(svga))
59bf215546Sopenharmony_ci         return SVGA3D_BLENDOP_BLENDFACTORALPHA;
60bf215546Sopenharmony_ci      else
61bf215546Sopenharmony_ci         return SVGA3D_BLENDOP_BLENDFACTOR; /* as close as we can get */
62bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
63bf215546Sopenharmony_ci      if (svga_have_vgpu10(svga))
64bf215546Sopenharmony_ci         return SVGA3D_BLENDOP_INVBLENDFACTORALPHA;
65bf215546Sopenharmony_ci      else
66bf215546Sopenharmony_ci         return SVGA3D_BLENDOP_INVBLENDFACTOR; /* as close as we can get */
67bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_COLOR:      return SVGA3D_BLENDOP_SRC1COLOR;
68bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_COLOR:  return SVGA3D_BLENDOP_INVSRC1COLOR;
69bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_SRC1_ALPHA:      return SVGA3D_BLENDOP_SRC1ALPHA;
70bf215546Sopenharmony_ci   case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:  return SVGA3D_BLENDOP_INVSRC1ALPHA;
71bf215546Sopenharmony_ci   case 0:                                return SVGA3D_BLENDOP_ONE;
72bf215546Sopenharmony_ci   default:
73bf215546Sopenharmony_ci      assert(0);
74bf215546Sopenharmony_ci      return SVGA3D_BLENDOP_ZERO;
75bf215546Sopenharmony_ci   }
76bf215546Sopenharmony_ci}
77bf215546Sopenharmony_ci
78bf215546Sopenharmony_cistatic inline unsigned
79bf215546Sopenharmony_cisvga_translate_blend_func(unsigned mode)
80bf215546Sopenharmony_ci{
81bf215546Sopenharmony_ci   switch (mode) {
82bf215546Sopenharmony_ci   case PIPE_BLEND_ADD:              return SVGA3D_BLENDEQ_ADD;
83bf215546Sopenharmony_ci   case PIPE_BLEND_SUBTRACT:         return SVGA3D_BLENDEQ_SUBTRACT;
84bf215546Sopenharmony_ci   case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT;
85bf215546Sopenharmony_ci   case PIPE_BLEND_MIN:              return SVGA3D_BLENDEQ_MINIMUM;
86bf215546Sopenharmony_ci   case PIPE_BLEND_MAX:              return SVGA3D_BLENDEQ_MAXIMUM;
87bf215546Sopenharmony_ci   default:
88bf215546Sopenharmony_ci      assert(0);
89bf215546Sopenharmony_ci      return SVGA3D_BLENDEQ_ADD;
90bf215546Sopenharmony_ci   }
91bf215546Sopenharmony_ci}
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci/**
95bf215546Sopenharmony_ci * Translate gallium logicop mode to SVGA3D logicop mode.
96bf215546Sopenharmony_ci */
97bf215546Sopenharmony_cistatic int
98bf215546Sopenharmony_citranslate_logicop(enum pipe_logicop op)
99bf215546Sopenharmony_ci{
100bf215546Sopenharmony_ci   switch (op) {
101bf215546Sopenharmony_ci   case PIPE_LOGICOP_CLEAR:
102bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_CLEAR;
103bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOR:
104bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_NOR;
105bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_INVERTED:
106bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_AND_INVERTED;
107bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY_INVERTED:
108bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_COPY_INVERTED;
109bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_REVERSE:
110bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_AND_REVERSE;
111bf215546Sopenharmony_ci   case PIPE_LOGICOP_INVERT:
112bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_INVERT;
113bf215546Sopenharmony_ci   case PIPE_LOGICOP_XOR:
114bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_XOR;
115bf215546Sopenharmony_ci   case PIPE_LOGICOP_NAND:
116bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_NAND;
117bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND:
118bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_AND;
119bf215546Sopenharmony_ci   case PIPE_LOGICOP_EQUIV:
120bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_EQUIV;
121bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOOP:
122bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_NOOP;
123bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_INVERTED:
124bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_OR_INVERTED;
125bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY:
126bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_COPY;
127bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_REVERSE:
128bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_OR_REVERSE;
129bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR:
130bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_OR;
131bf215546Sopenharmony_ci   case PIPE_LOGICOP_SET:
132bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_SET;
133bf215546Sopenharmony_ci   default:
134bf215546Sopenharmony_ci      return SVGA3D_DX11_LOGICOP_COPY;
135bf215546Sopenharmony_ci   }
136bf215546Sopenharmony_ci};
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci/**
140bf215546Sopenharmony_ci * Define a vgpu10 blend state object for the given
141bf215546Sopenharmony_ci * svga blend state.
142bf215546Sopenharmony_ci */
143bf215546Sopenharmony_cistatic void
144bf215546Sopenharmony_cidefine_blend_state_object(struct svga_context *svga,
145bf215546Sopenharmony_ci                          struct svga_blend_state *bs)
146bf215546Sopenharmony_ci{
147bf215546Sopenharmony_ci   SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
148bf215546Sopenharmony_ci   int i;
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   assert(svga_have_vgpu10(svga));
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   bs->id = util_bitmask_add(svga->blend_object_id_bm);
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) {
155bf215546Sopenharmony_ci      perRT[i].blendEnable = bs->rt[i].blend_enable;
156bf215546Sopenharmony_ci      perRT[i].srcBlend = bs->rt[i].srcblend;
157bf215546Sopenharmony_ci      perRT[i].destBlend = bs->rt[i].dstblend;
158bf215546Sopenharmony_ci      perRT[i].blendOp = bs->rt[i].blendeq;
159bf215546Sopenharmony_ci      perRT[i].srcBlendAlpha = bs->rt[i].srcblend_alpha;
160bf215546Sopenharmony_ci      perRT[i].destBlendAlpha = bs->rt[i].dstblend_alpha;
161bf215546Sopenharmony_ci      perRT[i].blendOpAlpha = bs->rt[i].blendeq_alpha;
162bf215546Sopenharmony_ci      perRT[i].renderTargetWriteMask = bs->rt[i].writemask;
163bf215546Sopenharmony_ci      perRT[i].logicOpEnable = bs->logicop_enabled;
164bf215546Sopenharmony_ci      perRT[i].logicOp = bs->logicop_mode;
165bf215546Sopenharmony_ci   }
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   SVGA_RETRY(svga, SVGA3D_vgpu10_DefineBlendState(svga->swc,
168bf215546Sopenharmony_ci                                                   bs->id,
169bf215546Sopenharmony_ci                                                   bs->alpha_to_coverage,
170bf215546Sopenharmony_ci                                                   bs->independent_blend_enable,
171bf215546Sopenharmony_ci                                                   perRT));
172bf215546Sopenharmony_ci}
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci/**
176bf215546Sopenharmony_ci * If SVGA3D_DEVCAP_LOGIC_BLENDOPS is false, we can't directly implement
177bf215546Sopenharmony_ci * GL's logicops.  But we can emulate some of them.  We set up the blending
178bf215546Sopenharmony_ci * state for that here.
179bf215546Sopenharmony_ci */
180bf215546Sopenharmony_cistatic void
181bf215546Sopenharmony_ciemulate_logicop(struct svga_context *svga,
182bf215546Sopenharmony_ci                unsigned logicop_func,
183bf215546Sopenharmony_ci                struct svga_blend_state *blend,
184bf215546Sopenharmony_ci                unsigned buffer)
185bf215546Sopenharmony_ci{
186bf215546Sopenharmony_ci   switch (logicop_func) {
187bf215546Sopenharmony_ci   case PIPE_LOGICOP_XOR:
188bf215546Sopenharmony_ci   case PIPE_LOGICOP_INVERT:
189bf215546Sopenharmony_ci      blend->need_white_fragments = TRUE;
190bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
191bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
192bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ONE;
193bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_SUBTRACT;
194bf215546Sopenharmony_ci      break;
195bf215546Sopenharmony_ci   case PIPE_LOGICOP_CLEAR:
196bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
197bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ZERO;
198bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
199bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
200bf215546Sopenharmony_ci      break;
201bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY:
202bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = FALSE;
203bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
204bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
205bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
206bf215546Sopenharmony_ci      break;
207bf215546Sopenharmony_ci   case PIPE_LOGICOP_COPY_INVERTED:
208bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable   = TRUE;
209bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
210bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
211bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
212bf215546Sopenharmony_ci      break;
213bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOOP:
214bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable   = TRUE;
215bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ZERO;
216bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
217bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
218bf215546Sopenharmony_ci      break;
219bf215546Sopenharmony_ci   case PIPE_LOGICOP_SET:
220bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
221bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
222bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ONE;
223bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
224bf215546Sopenharmony_ci      break;
225bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND:
226bf215546Sopenharmony_ci      /* Approximate with minimum - works for the 0 & anything case: */
227bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
228bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
229bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
230bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
231bf215546Sopenharmony_ci      break;
232bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_REVERSE:
233bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
234bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
235bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
236bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
237bf215546Sopenharmony_ci      break;
238bf215546Sopenharmony_ci   case PIPE_LOGICOP_AND_INVERTED:
239bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
240bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
241bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
242bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MINIMUM;
243bf215546Sopenharmony_ci      break;
244bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR:
245bf215546Sopenharmony_ci      /* Approximate with maximum - works for the 1 | anything case: */
246bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
247bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
248bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
249bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
250bf215546Sopenharmony_ci      break;
251bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_REVERSE:
252bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
253bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_SRCCOLOR;
254bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_INVDESTCOLOR;
255bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
256bf215546Sopenharmony_ci      break;
257bf215546Sopenharmony_ci   case PIPE_LOGICOP_OR_INVERTED:
258bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = TRUE;
259bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_INVSRCCOLOR;
260bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_DESTCOLOR;
261bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_MAXIMUM;
262bf215546Sopenharmony_ci      break;
263bf215546Sopenharmony_ci   case PIPE_LOGICOP_NAND:
264bf215546Sopenharmony_ci   case PIPE_LOGICOP_NOR:
265bf215546Sopenharmony_ci   case PIPE_LOGICOP_EQUIV:
266bf215546Sopenharmony_ci      /* Fill these in with plausible values */
267bf215546Sopenharmony_ci      blend->rt[buffer].blend_enable = FALSE;
268bf215546Sopenharmony_ci      blend->rt[buffer].srcblend       = SVGA3D_BLENDOP_ONE;
269bf215546Sopenharmony_ci      blend->rt[buffer].dstblend       = SVGA3D_BLENDOP_ZERO;
270bf215546Sopenharmony_ci      blend->rt[buffer].blendeq        = SVGA3D_BLENDEQ_ADD;
271bf215546Sopenharmony_ci      break;
272bf215546Sopenharmony_ci   default:
273bf215546Sopenharmony_ci      assert(0);
274bf215546Sopenharmony_ci      break;
275bf215546Sopenharmony_ci   }
276bf215546Sopenharmony_ci   blend->rt[buffer].srcblend_alpha = blend->rt[buffer].srcblend;
277bf215546Sopenharmony_ci   blend->rt[buffer].dstblend_alpha = blend->rt[buffer].dstblend;
278bf215546Sopenharmony_ci   blend->rt[buffer].blendeq_alpha = blend->rt[buffer].blendeq;
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   if (logicop_func == PIPE_LOGICOP_XOR) {
281bf215546Sopenharmony_ci      util_debug_message(&svga->debug.callback, CONFORMANCE,
282bf215546Sopenharmony_ci                         "XOR logicop mode has limited support");
283bf215546Sopenharmony_ci   }
284bf215546Sopenharmony_ci   else if (logicop_func != PIPE_LOGICOP_COPY) {
285bf215546Sopenharmony_ci      util_debug_message(&svga->debug.callback, CONFORMANCE,
286bf215546Sopenharmony_ci                         "general logicops are not supported");
287bf215546Sopenharmony_ci   }
288bf215546Sopenharmony_ci}
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_cistatic void *
293bf215546Sopenharmony_cisvga_create_blend_state(struct pipe_context *pipe,
294bf215546Sopenharmony_ci                        const struct pipe_blend_state *templ)
295bf215546Sopenharmony_ci{
296bf215546Sopenharmony_ci   struct svga_context *svga = svga_context(pipe);
297bf215546Sopenharmony_ci   struct svga_screen *ss = svga_screen(pipe->screen);
298bf215546Sopenharmony_ci   struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state );
299bf215546Sopenharmony_ci   unsigned i;
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci   if (!blend)
302bf215546Sopenharmony_ci      return NULL;
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci   /* Find index of first target with blending enabled.  If no blending is
305bf215546Sopenharmony_ci    * enabled at all, first_enabled will be zero.
306bf215546Sopenharmony_ci    */
307bf215546Sopenharmony_ci   unsigned first_enabled = 0;
308bf215546Sopenharmony_ci   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
309bf215546Sopenharmony_ci      if (templ->rt[i].blend_enable) {
310bf215546Sopenharmony_ci         first_enabled = i;
311bf215546Sopenharmony_ci         break;
312bf215546Sopenharmony_ci      }
313bf215546Sopenharmony_ci   }
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci   /* Fill in the per-rendertarget blend state.  We currently only
316bf215546Sopenharmony_ci    * support independent blend enable and colormask per render target.
317bf215546Sopenharmony_ci    */
318bf215546Sopenharmony_ci   for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
319bf215546Sopenharmony_ci      /* No way to set this in SVGA3D, and no way to correctly implement it on
320bf215546Sopenharmony_ci       * top of D3D9 API.  Instead we try to simulate with various blend modes.
321bf215546Sopenharmony_ci       */
322bf215546Sopenharmony_ci      if (templ->logicop_enable) {
323bf215546Sopenharmony_ci         if (ss->haveBlendLogicops) {
324bf215546Sopenharmony_ci            blend->logicop_enabled = TRUE;
325bf215546Sopenharmony_ci            blend->logicop_mode = translate_logicop(templ->logicop_func);
326bf215546Sopenharmony_ci            blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
327bf215546Sopenharmony_ci            blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD;
328bf215546Sopenharmony_ci            blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO;
329bf215546Sopenharmony_ci            blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
330bf215546Sopenharmony_ci            blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ZERO;
331bf215546Sopenharmony_ci            blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO;
332bf215546Sopenharmony_ci         }
333bf215546Sopenharmony_ci         else {
334bf215546Sopenharmony_ci            emulate_logicop(svga, templ->logicop_func, blend, i);
335bf215546Sopenharmony_ci         }
336bf215546Sopenharmony_ci      }
337bf215546Sopenharmony_ci      else {
338bf215546Sopenharmony_ci         /* Note: per-target blend terms are only supported for sm4_1
339bf215546Sopenharmony_ci          * device. For vgpu10 device, the blending terms must be identical
340bf215546Sopenharmony_ci          * for all targets (this is why we need the first_enabled index).
341bf215546Sopenharmony_ci          */
342bf215546Sopenharmony_ci         const unsigned j =
343bf215546Sopenharmony_ci            svga_have_sm4_1(svga) && templ->independent_blend_enable
344bf215546Sopenharmony_ci            ? i : first_enabled;
345bf215546Sopenharmony_ci         if (templ->independent_blend_enable || templ->rt[j].blend_enable) {
346bf215546Sopenharmony_ci            blend->rt[i].srcblend =
347bf215546Sopenharmony_ci               svga_translate_blend_factor(svga, templ->rt[j].rgb_src_factor);
348bf215546Sopenharmony_ci            blend->rt[i].dstblend =
349bf215546Sopenharmony_ci               svga_translate_blend_factor(svga, templ->rt[j].rgb_dst_factor);
350bf215546Sopenharmony_ci            blend->rt[i].blendeq =
351bf215546Sopenharmony_ci               svga_translate_blend_func(templ->rt[j].rgb_func);
352bf215546Sopenharmony_ci            blend->rt[i].srcblend_alpha =
353bf215546Sopenharmony_ci               svga_translate_blend_factor(svga, templ->rt[j].alpha_src_factor);
354bf215546Sopenharmony_ci            blend->rt[i].dstblend_alpha =
355bf215546Sopenharmony_ci               svga_translate_blend_factor(svga, templ->rt[j].alpha_dst_factor);
356bf215546Sopenharmony_ci            blend->rt[i].blendeq_alpha =
357bf215546Sopenharmony_ci               svga_translate_blend_func(templ->rt[j].alpha_func);
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci            if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend ||
360bf215546Sopenharmony_ci                blend->rt[i].dstblend_alpha != blend->rt[i].dstblend ||
361bf215546Sopenharmony_ci                blend->rt[i].blendeq_alpha  != blend->rt[i].blendeq) {
362bf215546Sopenharmony_ci               blend->rt[i].separate_alpha_blend_enable = TRUE;
363bf215546Sopenharmony_ci            }
364bf215546Sopenharmony_ci         }
365bf215546Sopenharmony_ci         else {
366bf215546Sopenharmony_ci            /* disabled - default blend terms */
367bf215546Sopenharmony_ci            blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
368bf215546Sopenharmony_ci            blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
369bf215546Sopenharmony_ci            blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
370bf215546Sopenharmony_ci            blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ONE;
371bf215546Sopenharmony_ci            blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO;
372bf215546Sopenharmony_ci            blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD;
373bf215546Sopenharmony_ci         }
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci         if (templ->independent_blend_enable) {
376bf215546Sopenharmony_ci            blend->rt[i].blend_enable = templ->rt[i].blend_enable;
377bf215546Sopenharmony_ci         }
378bf215546Sopenharmony_ci         else {
379bf215546Sopenharmony_ci            blend->rt[i].blend_enable = templ->rt[0].blend_enable;
380bf215546Sopenharmony_ci         }
381bf215546Sopenharmony_ci      }
382bf215546Sopenharmony_ci
383bf215546Sopenharmony_ci      /* Some GL blend modes are not supported by the VGPU9 device (there's
384bf215546Sopenharmony_ci       * no equivalent of PIPE_BLENDFACTOR_[INV_]CONST_ALPHA).
385bf215546Sopenharmony_ci       * When we set this flag, we copy the constant blend alpha value
386bf215546Sopenharmony_ci       * to the R, G, B components.
387bf215546Sopenharmony_ci       * This works as long as the src/dst RGB blend factors doesn't use
388bf215546Sopenharmony_ci       * PIPE_BLENDFACTOR_CONST_COLOR and PIPE_BLENDFACTOR_CONST_ALPHA
389bf215546Sopenharmony_ci       * at the same time.  There's no work-around for that.
390bf215546Sopenharmony_ci       */
391bf215546Sopenharmony_ci      if (!svga_have_vgpu10(svga)) {
392bf215546Sopenharmony_ci         if (templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
393bf215546Sopenharmony_ci             templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_CONST_ALPHA ||
394bf215546Sopenharmony_ci             templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA ||
395bf215546Sopenharmony_ci             templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA) {
396bf215546Sopenharmony_ci            blend->blend_color_alpha = TRUE;
397bf215546Sopenharmony_ci         }
398bf215546Sopenharmony_ci      }
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci      if (templ->independent_blend_enable) {
401bf215546Sopenharmony_ci         blend->rt[i].writemask = templ->rt[i].colormask;
402bf215546Sopenharmony_ci      }
403bf215546Sopenharmony_ci      else {
404bf215546Sopenharmony_ci         blend->rt[i].writemask = templ->rt[0].colormask;
405bf215546Sopenharmony_ci      }
406bf215546Sopenharmony_ci   }
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci   blend->independent_blend_enable = templ->independent_blend_enable;
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   blend->alpha_to_coverage = templ->alpha_to_coverage;
411bf215546Sopenharmony_ci   blend->alpha_to_one = templ->alpha_to_one;
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   if (svga_have_vgpu10(svga)) {
414bf215546Sopenharmony_ci      define_blend_state_object(svga, blend);
415bf215546Sopenharmony_ci   }
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   svga->hud.num_blend_objects++;
418bf215546Sopenharmony_ci   SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
419bf215546Sopenharmony_ci                        SVGA_STATS_COUNT_BLENDSTATE);
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci   return blend;
422bf215546Sopenharmony_ci}
423bf215546Sopenharmony_ci
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_cistatic void svga_bind_blend_state(struct pipe_context *pipe,
426bf215546Sopenharmony_ci                                  void *blend)
427bf215546Sopenharmony_ci{
428bf215546Sopenharmony_ci   struct svga_context *svga = svga_context(pipe);
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_ci   svga->curr.blend = (struct svga_blend_state*)blend;
431bf215546Sopenharmony_ci   svga->dirty |= SVGA_NEW_BLEND;
432bf215546Sopenharmony_ci}
433bf215546Sopenharmony_ci
434bf215546Sopenharmony_cistatic void svga_delete_blend_state(struct pipe_context *pipe,
435bf215546Sopenharmony_ci                                    void *blend)
436bf215546Sopenharmony_ci{
437bf215546Sopenharmony_ci   struct svga_context *svga = svga_context(pipe);
438bf215546Sopenharmony_ci   struct svga_blend_state *bs =
439bf215546Sopenharmony_ci      (struct svga_blend_state *) blend;
440bf215546Sopenharmony_ci
441bf215546Sopenharmony_ci   if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) {
442bf215546Sopenharmony_ci      SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id));
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci      if (bs->id == svga->state.hw_draw.blend_id)
445bf215546Sopenharmony_ci         svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID;
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci      util_bitmask_clear(svga->blend_object_id_bm, bs->id);
448bf215546Sopenharmony_ci      bs->id = SVGA3D_INVALID_ID;
449bf215546Sopenharmony_ci   }
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci   FREE(blend);
452bf215546Sopenharmony_ci   svga->hud.num_blend_objects--;
453bf215546Sopenharmony_ci}
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_cistatic void svga_set_blend_color( struct pipe_context *pipe,
456bf215546Sopenharmony_ci                                  const struct pipe_blend_color *blend_color )
457bf215546Sopenharmony_ci{
458bf215546Sopenharmony_ci   struct svga_context *svga = svga_context(pipe);
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ci   svga->curr.blend_color = *blend_color;
461bf215546Sopenharmony_ci
462bf215546Sopenharmony_ci   svga->dirty |= SVGA_NEW_BLEND_COLOR;
463bf215546Sopenharmony_ci}
464bf215546Sopenharmony_ci
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_civoid svga_init_blend_functions( struct svga_context *svga )
467bf215546Sopenharmony_ci{
468bf215546Sopenharmony_ci   svga->pipe.create_blend_state = svga_create_blend_state;
469bf215546Sopenharmony_ci   svga->pipe.bind_blend_state = svga_bind_blend_state;
470bf215546Sopenharmony_ci   svga->pipe.delete_blend_state = svga_delete_blend_state;
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_ci   svga->pipe.set_blend_color = svga_set_blend_color;
473bf215546Sopenharmony_ci}
474