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"
31 #include "svga_context.h"
33 #include "svga_hw_reg.h"
36 static INLINE
unsigned
37 svga_translate_blend_factor(unsigned factor
)
40 case PIPE_BLENDFACTOR_ZERO
: return SVGA3D_BLENDOP_ZERO
;
41 case PIPE_BLENDFACTOR_SRC_ALPHA
: return SVGA3D_BLENDOP_SRCALPHA
;
42 case PIPE_BLENDFACTOR_ONE
: return SVGA3D_BLENDOP_ONE
;
43 case PIPE_BLENDFACTOR_SRC_COLOR
: return SVGA3D_BLENDOP_SRCCOLOR
;
44 case PIPE_BLENDFACTOR_INV_SRC_COLOR
: return SVGA3D_BLENDOP_INVSRCCOLOR
;
45 case PIPE_BLENDFACTOR_DST_COLOR
: return SVGA3D_BLENDOP_DESTCOLOR
;
46 case PIPE_BLENDFACTOR_INV_DST_COLOR
: return SVGA3D_BLENDOP_INVDESTCOLOR
;
47 case PIPE_BLENDFACTOR_INV_SRC_ALPHA
: return SVGA3D_BLENDOP_INVSRCALPHA
;
48 case PIPE_BLENDFACTOR_DST_ALPHA
: return SVGA3D_BLENDOP_DESTALPHA
;
49 case PIPE_BLENDFACTOR_INV_DST_ALPHA
: return SVGA3D_BLENDOP_INVDESTALPHA
;
50 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
: return SVGA3D_BLENDOP_SRCALPHASAT
;
51 case PIPE_BLENDFACTOR_CONST_COLOR
: return SVGA3D_BLENDOP_BLENDFACTOR
;
52 case PIPE_BLENDFACTOR_INV_CONST_COLOR
: return SVGA3D_BLENDOP_INVBLENDFACTOR
;
53 case PIPE_BLENDFACTOR_CONST_ALPHA
: return SVGA3D_BLENDOP_BLENDFACTOR
; /* ? */
54 case PIPE_BLENDFACTOR_INV_CONST_ALPHA
: return SVGA3D_BLENDOP_INVBLENDFACTOR
; /* ? */
57 return SVGA3D_BLENDOP_ZERO
;
61 static INLINE
unsigned
62 svga_translate_blend_func(unsigned mode
)
65 case PIPE_BLEND_ADD
: return SVGA3D_BLENDEQ_ADD
;
66 case PIPE_BLEND_SUBTRACT
: return SVGA3D_BLENDEQ_SUBTRACT
;
67 case PIPE_BLEND_REVERSE_SUBTRACT
: return SVGA3D_BLENDEQ_REVSUBTRACT
;
68 case PIPE_BLEND_MIN
: return SVGA3D_BLENDEQ_MINIMUM
;
69 case PIPE_BLEND_MAX
: return SVGA3D_BLENDEQ_MAXIMUM
;
72 return SVGA3D_BLENDEQ_ADD
;
78 svga_create_blend_state(struct pipe_context
*pipe
,
79 const struct pipe_blend_state
*templ
)
81 struct svga_blend_state
*blend
= CALLOC_STRUCT( svga_blend_state
);
85 /* Fill in the per-rendertarget blend state. We currently only
86 * have one rendertarget.
88 for (i
= 0; i
< 1; i
++) {
89 /* No way to set this in SVGA3D, and no way to correctly implement it on
90 * top of D3D9 API. Instead we try to simulate with various blend modes.
92 if (templ
->logicop_enable
) {
93 switch (templ
->logicop_func
) {
94 case PIPE_LOGICOP_XOR
:
95 case PIPE_LOGICOP_INVERT
:
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_AND
:
130 /* Approximate with minimum - works for the 0 & anything case: */
131 blend
->rt
[i
].blend_enable
= TRUE
;
132 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
133 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
134 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
136 case PIPE_LOGICOP_AND_REVERSE
:
137 blend
->rt
[i
].blend_enable
= TRUE
;
138 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
139 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_INVDESTCOLOR
;
140 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
142 case PIPE_LOGICOP_AND_INVERTED
:
143 blend
->rt
[i
].blend_enable
= TRUE
;
144 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_INVSRCCOLOR
;
145 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
146 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MINIMUM
;
148 case PIPE_LOGICOP_OR
:
149 /* Approximate with maximum - works for the 1 | anything case: */
150 blend
->rt
[i
].blend_enable
= TRUE
;
151 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
152 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
153 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
155 case PIPE_LOGICOP_OR_REVERSE
:
156 blend
->rt
[i
].blend_enable
= TRUE
;
157 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_SRCCOLOR
;
158 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_INVDESTCOLOR
;
159 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
161 case PIPE_LOGICOP_OR_INVERTED
:
162 blend
->rt
[i
].blend_enable
= TRUE
;
163 blend
->rt
[i
].srcblend
= SVGA3D_BLENDOP_INVSRCCOLOR
;
164 blend
->rt
[i
].dstblend
= SVGA3D_BLENDOP_DESTCOLOR
;
165 blend
->rt
[i
].blendeq
= SVGA3D_BLENDEQ_MAXIMUM
;
167 case PIPE_LOGICOP_NAND
:
168 case PIPE_LOGICOP_NOR
:
169 case PIPE_LOGICOP_EQUIV
:
170 /* Fill these in with plausible values */
171 blend
->rt
[i
].blend_enable
= FALSE
;
179 blend
->rt
[i
].blend_enable
= templ
->rt
[0].blend_enable
;
181 if (templ
->rt
[0].blend_enable
) {
182 blend
->rt
[i
].srcblend
= svga_translate_blend_factor(templ
->rt
[0].rgb_src_factor
);
183 blend
->rt
[i
].dstblend
= svga_translate_blend_factor(templ
->rt
[0].rgb_dst_factor
);
184 blend
->rt
[i
].blendeq
= svga_translate_blend_func(templ
->rt
[0].rgb_func
);
185 blend
->rt
[i
].srcblend_alpha
= svga_translate_blend_factor(templ
->rt
[0].alpha_src_factor
);
186 blend
->rt
[i
].dstblend_alpha
= svga_translate_blend_factor(templ
->rt
[0].alpha_dst_factor
);
187 blend
->rt
[i
].blendeq_alpha
= svga_translate_blend_func(templ
->rt
[0].alpha_func
);
189 if (blend
->rt
[i
].srcblend_alpha
!= blend
->rt
[i
].srcblend
||
190 blend
->rt
[i
].dstblend_alpha
!= blend
->rt
[i
].dstblend
||
191 blend
->rt
[i
].blendeq_alpha
!= blend
->rt
[i
].blendeq
)
193 blend
->rt
[i
].separate_alpha_blend_enable
= TRUE
;
198 blend
->rt
[i
].writemask
= templ
->rt
[0].colormask
;
204 static void svga_bind_blend_state(struct pipe_context
*pipe
,
207 struct svga_context
*svga
= svga_context(pipe
);
209 svga
->curr
.blend
= (struct svga_blend_state
*)blend
;
210 svga
->dirty
|= SVGA_NEW_BLEND
;
214 static void svga_delete_blend_state(struct pipe_context
*pipe
, void *blend
)
219 static void svga_set_blend_color( struct pipe_context
*pipe
,
220 const struct pipe_blend_color
*blend_color
)
222 struct svga_context
*svga
= svga_context(pipe
);
224 svga
->curr
.blend_color
= *blend_color
;
226 svga
->dirty
|= SVGA_NEW_BLEND_COLOR
;
230 void svga_init_blend_functions( struct svga_context
*svga
)
232 svga
->pipe
.create_blend_state
= svga_create_blend_state
;
233 svga
->pipe
.bind_blend_state
= svga_bind_blend_state
;
234 svga
->pipe
.delete_blend_state
= svga_delete_blend_state
;
236 svga
->pipe
.set_blend_color
= svga_set_blend_color
;