1
/**********************************************************
2
* Copyright 2008-2009 VMware, Inc. All rights reserved.
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:
12
* The above copyright notice and this permission notice shall be
13
* included in all copies or substantial portions of the Software.
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
24
**********************************************************/
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"
32
#include "svga_context.h"
33
#include "svga_hw_reg.h"
37
static inline unsigned
38
svga_translate_blend_factor(const struct svga_context *svga, unsigned factor)
40
/* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so
41
* we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly.
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;
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;
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;
74
return SVGA3D_BLENDOP_ZERO;
78
static inline unsigned
79
svga_translate_blend_func(unsigned 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;
89
return SVGA3D_BLENDEQ_ADD;
95
* Translate gallium logicop mode to SVGA3D logicop mode.
98
translate_logicop(enum pipe_logicop 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;
134
return SVGA3D_DX11_LOGICOP_COPY;
140
* Define a vgpu10 blend state object for the given
144
define_blend_state_object(struct svga_context *svga,
145
struct svga_blend_state *bs)
147
SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS];
150
assert(svga_have_vgpu10(svga));
152
bs->id = util_bitmask_add(svga->blend_object_id_bm);
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;
167
SVGA_RETRY(svga, SVGA3D_vgpu10_DefineBlendState(svga->swc,
169
bs->alpha_to_coverage,
170
bs->independent_blend_enable,
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.
181
emulate_logicop(struct svga_context *svga,
182
unsigned logicop_func,
183
struct svga_blend_state *blend,
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
280
if (logicop_func == PIPE_LOGICOP_XOR) {
281
util_debug_message(&svga->debug.callback, CONFORMANCE,
282
"XOR logicop mode has limited support");
284
else if (logicop_func != PIPE_LOGICOP_COPY) {
285
util_debug_message(&svga->debug.callback, CONFORMANCE,
286
"general logicops are not supported");
293
svga_create_blend_state(struct pipe_context *pipe,
294
const struct pipe_blend_state *templ)
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 );
304
/* Find index of first target with blending enabled. If no blending is
305
* enabled at all, first_enabled will be zero.
307
unsigned first_enabled = 0;
308
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
309
if (templ->rt[i].blend_enable) {
315
/* Fill in the per-rendertarget blend state. We currently only
316
* support independent blend enable and colormask per render target.
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.
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;
334
emulate_logicop(svga, templ->logicop_func, blend, i);
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).
343
svga_have_sm4_1(svga) && templ->independent_blend_enable
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);
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;
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;
375
if (templ->independent_blend_enable) {
376
blend->rt[i].blend_enable = templ->rt[i].blend_enable;
379
blend->rt[i].blend_enable = templ->rt[0].blend_enable;
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.
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;
400
if (templ->independent_blend_enable) {
401
blend->rt[i].writemask = templ->rt[i].colormask;
404
blend->rt[i].writemask = templ->rt[0].colormask;
408
blend->independent_blend_enable = templ->independent_blend_enable;
410
blend->alpha_to_coverage = templ->alpha_to_coverage;
411
blend->alpha_to_one = templ->alpha_to_one;
413
if (svga_have_vgpu10(svga)) {
414
define_blend_state_object(svga, blend);
417
svga->hud.num_blend_objects++;
418
SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws,
419
SVGA_STATS_COUNT_BLENDSTATE);
425
static void svga_bind_blend_state(struct pipe_context *pipe,
428
struct svga_context *svga = svga_context(pipe);
430
svga->curr.blend = (struct svga_blend_state*)blend;
431
svga->dirty |= SVGA_NEW_BLEND;
434
static void svga_delete_blend_state(struct pipe_context *pipe,
437
struct svga_context *svga = svga_context(pipe);
438
struct svga_blend_state *bs =
439
(struct svga_blend_state *) blend;
441
if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) {
442
SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id));
444
if (bs->id == svga->state.hw_draw.blend_id)
445
svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID;
447
util_bitmask_clear(svga->blend_object_id_bm, bs->id);
448
bs->id = SVGA3D_INVALID_ID;
452
svga->hud.num_blend_objects--;
455
static void svga_set_blend_color( struct pipe_context *pipe,
456
const struct pipe_blend_color *blend_color )
458
struct svga_context *svga = svga_context(pipe);
460
svga->curr.blend_color = *blend_color;
462
svga->dirty |= SVGA_NEW_BLEND_COLOR;
466
void svga_init_blend_functions( struct svga_context *svga )
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;
472
svga->pipe.set_blend_color = svga_set_blend_color;