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