Tizen 2.0 Release
[profile/ivi/osmesa.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    if (blend == NULL)
115       return NULL;
116
117    if (templ->logicop_enable) {
118       blend->cc2.logicop_enable = 1;
119       blend->cc5.logicop_func = translate_logicop(templ->logicop_func);
120    } 
121    else if (templ->rt[0].blend_enable) {
122       blend->cc6.dest_blend_factor = translate_blend_factor(templ->rt[0].rgb_dst_factor);
123       blend->cc6.src_blend_factor = translate_blend_factor(templ->rt[0].rgb_src_factor);
124       blend->cc6.blend_function = translate_blend_equation(templ->rt[0].rgb_func);
125
126       blend->cc5.ia_dest_blend_factor = translate_blend_factor(templ->rt[0].alpha_dst_factor);
127       blend->cc5.ia_src_blend_factor = translate_blend_factor(templ->rt[0].alpha_src_factor);
128       blend->cc5.ia_blend_function = translate_blend_equation(templ->rt[0].alpha_func);
129
130       blend->cc3.blend_enable = 1;
131       blend->cc3.ia_blend_enable = 
132          (blend->cc6.dest_blend_factor != blend->cc5.ia_dest_blend_factor ||
133           blend->cc6.src_blend_factor != blend->cc5.ia_src_blend_factor ||
134           blend->cc6.blend_function != blend->cc5.ia_blend_function);
135
136       /* Per-surface blend enables, currently just follow global
137        * state:
138        */
139       blend->ss0.color_blend = 1;
140    }
141
142    blend->cc5.dither_enable = templ->dither;
143
144    if (BRW_DEBUG & DEBUG_STATS)
145       blend->cc5.statistics_enable = 1;
146
147    /* Per-surface color mask -- just follow global state:
148     */
149    blend->ss0.writedisable_red   = (templ->rt[0].colormask & PIPE_MASK_R) ? 0 : 1;
150    blend->ss0.writedisable_green = (templ->rt[0].colormask & PIPE_MASK_G) ? 0 : 1;
151    blend->ss0.writedisable_blue  = (templ->rt[0].colormask & PIPE_MASK_B) ? 0 : 1;
152    blend->ss0.writedisable_alpha = (templ->rt[0].colormask & PIPE_MASK_A) ? 0 : 1;
153
154    return (void *)blend;
155 }
156
157 static void brw_bind_blend_state(struct pipe_context *pipe,
158                                  void *cso)
159 {
160    struct brw_context *brw = brw_context(pipe);
161    brw->curr.blend = (const struct brw_blend_state *)cso;
162    brw->state.dirty.mesa |= PIPE_NEW_BLEND;
163 }
164
165 static void brw_delete_blend_state(struct pipe_context *pipe,
166                                   void *cso)
167 {
168    struct brw_context *brw = brw_context(pipe);
169    assert((const void *)cso != (const void *)brw->curr.blend);
170    FREE(cso);
171 }
172
173
174 static void brw_set_blend_color(struct pipe_context *pipe,
175                                 const struct pipe_blend_color *blend_color)
176 {
177    struct brw_context *brw = brw_context(pipe);
178    struct brw_blend_constant_color *bcc = &brw->curr.bcc;
179
180    bcc->blend_constant_color[0] = blend_color->color[0];
181    bcc->blend_constant_color[1] = blend_color->color[1];
182    bcc->blend_constant_color[2] = blend_color->color[2];
183    bcc->blend_constant_color[3] = blend_color->color[3];
184
185    brw->state.dirty.mesa |= PIPE_NEW_BLEND_COLOR;
186 }
187
188
189 void brw_pipe_blend_init( struct brw_context *brw )
190 {
191    brw->base.set_blend_color = brw_set_blend_color;
192    brw->base.create_blend_state = brw_create_blend_state;
193    brw->base.bind_blend_state = brw_bind_blend_state;
194    brw->base.delete_blend_state = brw_delete_blend_state;
195
196    {
197       struct brw_blend_constant_color *bcc = &brw->curr.bcc;
198
199       memset(bcc, 0, sizeof(*bcc));      
200       bcc->header.opcode = CMD_BLEND_CONSTANT_COLOR;
201       bcc->header.length = sizeof(*bcc)/4-2;
202    }
203
204 }
205
206 void brw_pipe_blend_cleanup( struct brw_context *brw )
207 {
208 }