cc9ee2e8dbc5500e52b9bc003d09edbb0775ab44
[mesa.git] / src / gallium / drivers / i965 / brw_pipe_blend.c
1
2 #include "util/u_memory.h"
3 #include "pipe/p_context.h"
4 #include "pipe/p_state.h"
5
6 #include "brw_context.h"
7 #include "brw_defines.h"
8 #include "brw_debug.h"
9
10 static int translate_logicop(unsigned logicop)
11 {
12 switch (logicop) {
13 case PIPE_LOGICOP_CLEAR:
14 return BRW_LOGICOPFUNCTION_CLEAR;
15 case PIPE_LOGICOP_AND:
16 return BRW_LOGICOPFUNCTION_AND;
17 case PIPE_LOGICOP_AND_REVERSE:
18 return BRW_LOGICOPFUNCTION_AND_REVERSE;
19 case PIPE_LOGICOP_COPY:
20 return BRW_LOGICOPFUNCTION_COPY;
21 case PIPE_LOGICOP_COPY_INVERTED:
22 return BRW_LOGICOPFUNCTION_COPY_INVERTED;
23 case PIPE_LOGICOP_AND_INVERTED:
24 return BRW_LOGICOPFUNCTION_AND_INVERTED;
25 case PIPE_LOGICOP_NOOP:
26 return BRW_LOGICOPFUNCTION_NOOP;
27 case PIPE_LOGICOP_XOR:
28 return BRW_LOGICOPFUNCTION_XOR;
29 case PIPE_LOGICOP_OR:
30 return BRW_LOGICOPFUNCTION_OR;
31 case PIPE_LOGICOP_OR_INVERTED:
32 return BRW_LOGICOPFUNCTION_OR_INVERTED;
33 case PIPE_LOGICOP_NOR:
34 return BRW_LOGICOPFUNCTION_NOR;
35 case PIPE_LOGICOP_EQUIV:
36 return BRW_LOGICOPFUNCTION_EQUIV;
37 case PIPE_LOGICOP_INVERT:
38 return BRW_LOGICOPFUNCTION_INVERT;
39 case PIPE_LOGICOP_OR_REVERSE:
40 return BRW_LOGICOPFUNCTION_OR_REVERSE;
41 case PIPE_LOGICOP_NAND:
42 return BRW_LOGICOPFUNCTION_NAND;
43 case PIPE_LOGICOP_SET:
44 return BRW_LOGICOPFUNCTION_SET;
45 default:
46 assert(0);
47 return BRW_LOGICOPFUNCTION_SET;
48 }
49 }
50
51
52 static unsigned translate_blend_equation( unsigned mode )
53 {
54 switch (mode) {
55 case PIPE_BLEND_ADD:
56 return BRW_BLENDFUNCTION_ADD;
57 case PIPE_BLEND_MIN:
58 return BRW_BLENDFUNCTION_MIN;
59 case PIPE_BLEND_MAX:
60 return BRW_BLENDFUNCTION_MAX;
61 case PIPE_BLEND_SUBTRACT:
62 return BRW_BLENDFUNCTION_SUBTRACT;
63 case PIPE_BLEND_REVERSE_SUBTRACT:
64 return BRW_BLENDFUNCTION_REVERSE_SUBTRACT;
65 default:
66 assert(0);
67 return BRW_BLENDFUNCTION_ADD;
68 }
69 }
70
71 static unsigned translate_blend_factor( unsigned factor )
72 {
73 switch(factor) {
74 case PIPE_BLENDFACTOR_ZERO:
75 return BRW_BLENDFACTOR_ZERO;
76 case PIPE_BLENDFACTOR_SRC_ALPHA:
77 return BRW_BLENDFACTOR_SRC_ALPHA;
78 case PIPE_BLENDFACTOR_ONE:
79 return BRW_BLENDFACTOR_ONE;
80 case PIPE_BLENDFACTOR_SRC_COLOR:
81 return BRW_BLENDFACTOR_SRC_COLOR;
82 case PIPE_BLENDFACTOR_INV_SRC_COLOR:
83 return BRW_BLENDFACTOR_INV_SRC_COLOR;
84 case PIPE_BLENDFACTOR_DST_COLOR:
85 return BRW_BLENDFACTOR_DST_COLOR;
86 case PIPE_BLENDFACTOR_INV_DST_COLOR:
87 return BRW_BLENDFACTOR_INV_DST_COLOR;
88 case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
89 return BRW_BLENDFACTOR_INV_SRC_ALPHA;
90 case PIPE_BLENDFACTOR_DST_ALPHA:
91 return BRW_BLENDFACTOR_DST_ALPHA;
92 case PIPE_BLENDFACTOR_INV_DST_ALPHA:
93 return BRW_BLENDFACTOR_INV_DST_ALPHA;
94 case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
95 return BRW_BLENDFACTOR_SRC_ALPHA_SATURATE;
96 case PIPE_BLENDFACTOR_CONST_COLOR:
97 return BRW_BLENDFACTOR_CONST_COLOR;
98 case PIPE_BLENDFACTOR_INV_CONST_COLOR:
99 return BRW_BLENDFACTOR_INV_CONST_COLOR;
100 case PIPE_BLENDFACTOR_CONST_ALPHA:
101 return BRW_BLENDFACTOR_CONST_ALPHA;
102 case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
103 return BRW_BLENDFACTOR_INV_CONST_ALPHA;
104 default:
105 assert(0);
106 return BRW_BLENDFACTOR_ZERO;
107 }
108 }
109
110 static void *brw_create_blend_state( struct pipe_context *pipe,
111 const struct pipe_blend_state *templ )
112 {
113 struct brw_blend_state *blend = CALLOC_STRUCT(brw_blend_state);
114
115 if (templ->logicop_enable) {
116 blend->cc2.logicop_enable = 1;
117 blend->cc5.logicop_func = translate_logicop(templ->logicop_func);
118 }
119 else if (templ->blend_enable) {
120 blend->cc6.dest_blend_factor = translate_blend_factor(templ->rgb_dst_factor);
121 blend->cc6.src_blend_factor = translate_blend_factor(templ->rgb_src_factor);
122 blend->cc6.blend_function = translate_blend_equation(templ->rgb_func);
123
124 blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->alpha_dst_factor);
125 blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->alpha_src_factor);
126 blend->cc5.ia_blend_function = translate_blend_equation(templ->alpha_func);
127
128 blend->cc3.blend_enable = 1;
129 blend->cc3.ia_blend_enable =
130 (blend->cc6.dest_blend_factor != blend->cc5.ia_dest_blend_factor ||
131 blend->cc6.src_blend_factor != blend->cc5.ia_src_blend_factor ||
132 blend->cc6.blend_function != blend->cc5.ia_blend_function);
133
134 /* Per-surface blend enables, currently just follow global
135 * state:
136 */
137 blend->ss0.color_blend = 1;
138 }
139
140 blend->cc5.dither_enable = templ->dither;
141
142 if (BRW_DEBUG & DEBUG_STATS)
143 blend->cc5.statistics_enable = 1;
144
145 /* Per-surface color mask -- just follow global state:
146 */
147 blend->ss0.writedisable_red = (templ->colormask & PIPE_MASK_R) ? 1 : 0;
148 blend->ss0.writedisable_green = (templ->colormask & PIPE_MASK_G) ? 1 : 0;
149 blend->ss0.writedisable_blue = (templ->colormask & PIPE_MASK_B) ? 1 : 0;
150 blend->ss0.writedisable_alpha = (templ->colormask & PIPE_MASK_A) ? 1 : 0;
151
152 return (void *)blend;
153 }
154
155 static void brw_bind_blend_state(struct pipe_context *pipe,
156 void *cso)
157 {
158 struct brw_context *brw = brw_context(pipe);
159 brw->curr.blend = (const struct brw_blend_state *)cso;
160 brw->state.dirty.mesa |= PIPE_NEW_BLEND;
161 }
162
163 static void brw_delete_blend_state(struct pipe_context *pipe,
164 void *cso)
165 {
166 struct brw_context *brw = brw_context(pipe);
167 assert((const void *)cso != (const void *)brw->curr.blend);
168 FREE(cso);
169 }
170
171
172 static void brw_set_blend_color(struct pipe_context *pipe,
173 const struct pipe_blend_color *blend_color)
174 {
175 struct brw_context *brw = brw_context(pipe);
176 struct brw_blend_constant_color *bcc = &brw->curr.bcc;
177
178 memset(bcc, 0, sizeof(*bcc));
179 bcc->header.opcode = CMD_BLEND_CONSTANT_COLOR;
180 bcc->header.length = sizeof(*bcc)/4-2;
181 bcc->blend_constant_color[0] = blend_color->color[0];
182 bcc->blend_constant_color[1] = blend_color->color[1];
183 bcc->blend_constant_color[2] = blend_color->color[2];
184 bcc->blend_constant_color[3] = blend_color->color[3];
185
186 brw->state.dirty.mesa |= PIPE_NEW_BLEND_COLOR;
187 }
188
189
190 void brw_pipe_blend_init( struct brw_context *brw )
191 {
192 brw->base.set_blend_color = brw_set_blend_color;
193 brw->base.create_blend_state = brw_create_blend_state;
194 brw->base.bind_blend_state = brw_bind_blend_state;
195 brw->base.delete_blend_state = brw_delete_blend_state;
196 }
197
198 void brw_pipe_blend_cleanup( struct brw_context *brw )
199 {
200 }