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 "pipe/p_inlines.h"
27 #include "pipe/p_defines.h"
28 #include "util/u_math.h"
29 #include "util/u_memory.h"
31 #include "svga_context.h"
32 #include "svga_state.h"
34 #include "svga_hw_reg.h"
37 static INLINE
unsigned
38 svga_translate_blend_factor(unsigned factor
)
41 case PIPE_BLENDFACTOR_ZERO
: return SVGA3D_BLENDOP_ZERO
;
42 case PIPE_BLENDFACTOR_SRC_ALPHA
: return SVGA3D_BLENDOP_SRCALPHA
;
43 case PIPE_BLENDFACTOR_ONE
: return SVGA3D_BLENDOP_ONE
;
44 case PIPE_BLENDFACTOR_SRC_COLOR
: return SVGA3D_BLENDOP_SRCCOLOR
;
45 case PIPE_BLENDFACTOR_INV_SRC_COLOR
: return SVGA3D_BLENDOP_INVSRCCOLOR
;
46 case PIPE_BLENDFACTOR_DST_COLOR
: return SVGA3D_BLENDOP_DESTCOLOR
;
47 case PIPE_BLENDFACTOR_INV_DST_COLOR
: return SVGA3D_BLENDOP_INVDESTCOLOR
;
48 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
: return SVGA3D_BLENDOP_INVSRCALPHA
;
49 case PIPE_BLENDFACTOR_DST_ALPHA
: return SVGA3D_BLENDOP_DESTALPHA
;
50 case PIPE_BLENDFACTOR_INV_DST_ALPHA
: return SVGA3D_BLENDOP_INVDESTALPHA
;
51 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
: return SVGA3D_BLENDOP_SRCALPHASAT
;
52 case PIPE_BLENDFACTOR_CONST_COLOR
: return SVGA3D_BLENDOP_BLENDFACTOR
;
53 case PIPE_BLENDFACTOR_INV_CONST_COLOR
: return SVGA3D_BLENDOP_INVBLENDFACTOR
;
54 case PIPE_BLENDFACTOR_CONST_ALPHA
: return SVGA3D_BLENDOP_BLENDFACTOR
; /* ? */
55 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
: return SVGA3D_BLENDOP_INVBLENDFACTOR
; /* ? */
58 return SVGA3D_BLENDOP_ZERO
;
62 static INLINE
unsigned
63 svga_translate_blend_func(unsigned mode
)
66 case PIPE_BLEND_ADD
: return SVGA3D_BLENDEQ_ADD
;
67 case PIPE_BLEND_SUBTRACT
: return SVGA3D_BLENDEQ_SUBTRACT
;
68 case PIPE_BLEND_REVERSE_SUBTRACT
: return SVGA3D_BLENDEQ_REVSUBTRACT
;
69 case PIPE_BLEND_MIN
: return SVGA3D_BLENDEQ_MINIMUM
;
70 case PIPE_BLEND_MAX
: return SVGA3D_BLENDEQ_MAXIMUM
;
73 return SVGA3D_BLENDEQ_ADD
;
79 svga_create_blend_state(struct pipe_context
*pipe
,
80 const struct pipe_blend_state
*templ
)
82 struct svga_blend_state
*blend
= CALLOC_STRUCT( svga_blend_state
);
86 /* Fill in the per-rendertarget blend state. We currently only
87 * have one rendertarget.
89 for (i
= 0; i
< 1; i
++) {
90 /* No way to set this in SVGA3D, and no way to correctly implement it on
91 * top of D3D9 API. Instead we try to simulate with various blend modes.
93 if (templ
->logicop_enable
) {
94 switch (templ
->logicop_func
) {
95 case PIPE_LOGICOP_XOR
:
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
;
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
;
108 case PIPE_LOGICOP_COPY
:
109 blend
->rt
[i
].blend_enable
= FALSE
;
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
;
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
;
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
;
129 case PIPE_LOGICOP_INVERT
:
130 blend
->rt
[i
].blend_enable
= TRUE
;
131 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_INVSRCCOLOR
;
132 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_ZERO
;
133 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_ADD
;
135 case PIPE_LOGICOP_AND
:
136 /* Approximate with minimum - works for the 0 & anything case: */
137 blend
->rt
[i
].blend_enable
= TRUE
;
138 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
139 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
140 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
142 case PIPE_LOGICOP_AND_REVERSE
:
143 blend
->rt
[i
].blend_enable
= TRUE
;
144 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
145 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_INVDESTCOLOR
;
146 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
148 case PIPE_LOGICOP_AND_INVERTED
:
149 blend
->rt
[i
].blend_enable
= TRUE
;
150 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_INVSRCCOLOR
;
151 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
152 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
154 case PIPE_LOGICOP_OR
:
155 /* Approximate with maximum - works for the 1 | anything case: */
156 blend
->rt
[i
].blend_enable
= TRUE
;
157 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
158 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
159 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
161 case PIPE_LOGICOP_OR_REVERSE
:
162 blend
->rt
[i
].blend_enable
= TRUE
;
163 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
164 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_INVDESTCOLOR
;
165 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
167 case PIPE_LOGICOP_OR_INVERTED
:
168 blend
->rt
[i
].blend_enable
= TRUE
;
169 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_INVSRCCOLOR
;
170 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
171 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
173 case PIPE_LOGICOP_NAND
:
174 case PIPE_LOGICOP_NOR
:
175 case PIPE_LOGICOP_EQUIV
:
176 /* Fill these in with plausible values */
177 blend
->rt
[i
].blend_enable
= FALSE
;
185 blend
->rt
[i
].blend_enable
= templ
->blend_enable
;
187 if (templ
->blend_enable
) {
188 blend
->rt
[i
].srcblend
= svga_translate_blend_factor(templ
->rgb_src_factor
);
189 blend
->rt
[i
].dstblend
= svga_translate_blend_factor(templ
->rgb_dst_factor
);
190 blend
->rt
[i
].blendeq
= svga_translate_blend_func(templ
->rgb_func
);
191 blend
->rt
[i
].srcblend_alpha
= svga_translate_blend_factor(templ
->alpha_src_factor
);
192 blend
->rt
[i
].dstblend_alpha
= svga_translate_blend_factor(templ
->alpha_dst_factor
);
193 blend
->rt
[i
].blendeq_alpha
= svga_translate_blend_func(templ
->alpha_func
);
195 if (blend
->rt
[i
].srcblend_alpha
!= blend
->rt
[i
].srcblend
||
196 blend
->rt
[i
].dstblend_alpha
!= blend
->rt
[i
].dstblend
||
197 blend
->rt
[i
].blendeq_alpha
!= blend
->rt
[i
].blendeq
)
199 blend
->rt
[i
].separate_alpha_blend_enable
= TRUE
;
204 blend
->rt
[i
].writemask
= templ
->colormask
;
210 static void svga_bind_blend_state(struct pipe_context
*pipe
,
213 struct svga_context
*svga
= svga_context(pipe
);
215 svga
->curr
.blend
= (struct svga_blend_state
*)blend
;
216 svga
->dirty
|= SVGA_NEW_BLEND
;
220 static void svga_delete_blend_state(struct pipe_context
*pipe
, void *blend
)
225 static void svga_set_blend_color( struct pipe_context
*pipe
,
226 const struct pipe_blend_color
*blend_color
)
228 struct svga_context
*svga
= svga_context(pipe
);
230 svga
->curr
.blend_color
= *blend_color
;
232 svga
->dirty
|= SVGA_NEW_BLEND
;
236 void svga_init_blend_functions( struct svga_context
*svga
)
238 svga
->pipe
.create_blend_state
= svga_create_blend_state
;
239 svga
->pipe
.bind_blend_state
= svga_bind_blend_state
;
240 svga
->pipe
.delete_blend_state
= svga_delete_blend_state
;
242 svga
->pipe
.set_blend_color
= svga_set_blend_color
;