st/xorg: set blend state for exa
[mesa.git] / src / gallium / state_trackers / xorg / xorg_composite.c
1 #include "xorg_composite.h"
2
3 #include <cso_cache/cso_context.h>
4
5 #include <pipe/p_inlines.h>
6
7 struct xorg_composite_blend {
8 int op:8;
9
10 unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */
11 unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
12
13 unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */
14 unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
15 };
16
17 #define BLEND_OP_OVER 3
18 static const struct xorg_composite_blend xorg_blends[] = {
19 { PictOpClear,
20 PIPE_BLENDFACTOR_CONST_COLOR, PIPE_BLENDFACTOR_CONST_ALPHA,
21 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO },
22
23 { PictOpSrc,
24 PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE,
25 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO },
26
27 { PictOpDst,
28 PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO,
29 PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE },
30
31 { PictOpOver,
32 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
33 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
34
35 { PictOpOverReverse,
36 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
37 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
38 };
39
40 struct acceleration_info {
41 int op : 16;
42 int with_mask : 1;
43 int component_alpha : 1;
44 };
45 static const struct acceleration_info accelerated_ops[] = {
46 {PictOpClear, 1, 0},
47 {PictOpSrc, 1, 0},
48 {PictOpDst, 1, 0},
49 {PictOpOver, 1, 0},
50 {PictOpOverReverse, 1, 0},
51 {PictOpIn, 1, 0},
52 {PictOpInReverse, 1, 0},
53 {PictOpOut, 1, 0},
54 {PictOpOutReverse, 1, 0},
55 {PictOpAtop, 1, 0},
56 {PictOpAtopReverse, 1, 0},
57 {PictOpXor, 1, 0},
58 {PictOpAdd, 1, 0},
59 {PictOpSaturate, 1, 0},
60 };
61
62 static struct xorg_composite_blend
63 blend_for_op(int op)
64 {
65 const int num_blends =
66 sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
67 int i;
68
69 for (i = 0; i < num_blends; ++i) {
70 if (xorg_blends[i].op == op)
71 return xorg_blends[i];
72 }
73 return xorg_blends[BLEND_OP_OVER];
74 }
75
76 static void
77 draw_texture(struct exa_context *exa)
78 {
79 #if 0
80 if (buf) {
81 util_draw_vertex_buffer(pipe, buf, 0,
82 PIPE_PRIM_TRIANGLE_FAN,
83 4, /* verts */
84 2); /* attribs/vert */
85
86 pipe_buffer_reference(&buf, NULL);
87 }
88 #endif
89 }
90
91 boolean xorg_composite_accelerated(int op,
92 PicturePtr pSrcPicture,
93 PicturePtr pMaskPicture,
94 PicturePtr pDstPicture)
95 {
96 unsigned i;
97 unsigned accel_ops_count =
98 sizeof(accelerated_ops)/sizeof(struct acceleration_info);
99
100 if (pSrcPicture) {
101 /* component alpha not supported */
102 if (pSrcPicture->componentAlpha)
103 return FALSE;
104 /* fills not supported */
105 if (pSrcPicture->pSourcePict)
106 return FALSE;
107 }
108
109 for (i = 0; i < accel_ops_count; ++i) {
110 if (op == accelerated_ops[i].op) {
111 if (pMaskPicture && !accelerated_ops[i].with_mask)
112 return FALSE;
113 return TRUE;
114 }
115 }
116 return FALSE;
117 }
118
119 static void
120 bind_framebuffer_state(struct exa_context *exa, PicturePtr pDstPicture,
121 struct exa_pixmap_priv *pDst)
122 {
123 unsigned i;
124 struct pipe_framebuffer_state state;
125 struct pipe_surface *surface = exa_gpu_surface(exa, pDst);
126 memset(&state, 0, sizeof(struct pipe_framebuffer_state));
127
128 state.width = pDstPicture->pDrawable->width;
129 state.height = pDstPicture->pDrawable->height;
130
131 state.nr_cbufs = 1;
132 state.cbufs[0] = surface;
133 for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
134 state.cbufs[i] = 0;
135
136 /* currently we don't use depth/stencil */
137 state.zsbuf = 0;
138
139 cso_set_framebuffer(exa->cso, &state);
140 }
141
142 enum AxisOrientation {
143 Y0_BOTTOM,
144 Y0_TOP
145 };
146
147 static void
148 set_viewport(struct exa_context *exa, int width, int height,
149 enum AxisOrientation orientation)
150 {
151 struct pipe_viewport_state viewport;
152 float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f;
153
154 viewport.scale[0] = width / 2.f;
155 viewport.scale[1] = height / y_scale;
156 viewport.scale[2] = 1.0;
157 viewport.scale[3] = 1.0;
158 viewport.translate[0] = width / 2.f;
159 viewport.translate[1] = height / 2.f;
160 viewport.translate[2] = 0.0;
161 viewport.translate[3] = 0.0;
162
163 cso_set_viewport(exa->cso, &viewport);
164 }
165
166 static void
167 bind_viewport_state(struct exa_context *exa, PicturePtr pDstPicture)
168 {
169 const int param_bytes = 8 * sizeof(float);
170 int width = pDstPicture->pDrawable->width;
171 int height = pDstPicture->pDrawable->height;
172 float vs_consts[8] = {
173 2.f/width, 2.f/height, 1, 1,
174 -1, -1, 0, 0
175 };
176 struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
177
178 set_viewport(exa, width, height, Y0_BOTTOM);
179
180 pipe_buffer_reference(&cbuf->buffer, NULL);
181 cbuf->buffer = pipe_buffer_create(exa->ctx->screen, 16,
182 PIPE_BUFFER_USAGE_CONSTANT,
183 param_bytes);
184
185 if (cbuf->buffer) {
186 pipe_buffer_write(exa->ctx->screen, cbuf->buffer,
187 0, param_bytes, vs_consts);
188 }
189 exa->ctx->set_constant_buffer(exa->ctx, PIPE_SHADER_VERTEX, 0, cbuf);
190 }
191
192 static void
193 bind_blend_state(struct exa_context *exa, int op,
194 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
195 {
196 boolean component_alpha = pSrcPicture->componentAlpha;
197 struct xorg_composite_blend blend_opt;
198 struct pipe_blend_state blend;
199
200 if (component_alpha) {
201 op = PictOpOver;
202 }
203 blend_opt = blend_for_op(op);
204
205 memset(&blend, 0, sizeof(struct pipe_blend_state));
206 blend.blend_enable = 1;
207 blend.colormask |= PIPE_MASK_R;
208 blend.colormask |= PIPE_MASK_G;
209 blend.colormask |= PIPE_MASK_B;
210 blend.colormask |= PIPE_MASK_A;
211
212 blend.rgb_src_factor = blend_opt.rgb_src_factor;
213 blend.alpha_src_factor = blend_opt.alpha_src_factor;
214 blend.rgb_dst_factor = blend_opt.rgb_dst_factor;
215 blend.alpha_dst_factor = blend_opt.alpha_dst_factor;
216
217 cso_set_blend(exa->cso, &blend);
218 }
219
220 static void
221 bind_rasterizer_state()
222 {
223 }
224
225 static void
226 bind_shaders()
227 {
228 }
229
230
231 boolean xorg_composite_bind_state(struct exa_context *exa,
232 int op,
233 PicturePtr pSrcPicture,
234 PicturePtr pMaskPicture,
235 PicturePtr pDstPicture,
236 struct exa_pixmap_priv *pSrc,
237 struct exa_pixmap_priv *pMask,
238 struct exa_pixmap_priv *pDst)
239 {
240 bind_framebuffer_state(exa, pDstPicture, pDst);
241 bind_viewport_state(exa, pDstPicture);
242 bind_blend_state(exa, op, pSrcPicture, pMaskPicture);
243 bind_rasterizer_state();
244 bind_shaders();
245
246 return FALSE;
247 }
248
249 void xorg_composite(struct exa_context *exa,
250 struct exa_pixmap_priv *dst,
251 int srcX, int srcY, int maskX, int maskY,
252 int dstX, int dstY, int width, int height)
253 {
254 }
255