1 #include "xorg_composite.h"
3 #include "xorg_renderer.h"
4 #include "xorg_exa_tgsi.h"
6 #include "cso_cache/cso_context.h"
7 #include "util/u_draw_quad.h"
8 #include "util/u_math.h"
10 #include "pipe/p_inlines.h"
12 struct xorg_composite_blend
{
15 unsigned rgb_src_factor
:5; /**< PIPE_BLENDFACTOR_x */
16 unsigned alpha_src_factor
:5; /**< PIPE_BLENDFACTOR_x */
18 unsigned rgb_dst_factor
:5; /**< PIPE_BLENDFACTOR_x */
19 unsigned alpha_dst_factor
:5; /**< PIPE_BLENDFACTOR_x */
22 #define BLEND_OP_OVER 3
23 static const struct xorg_composite_blend xorg_blends
[] = {
25 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
,
26 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
},
29 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
,
30 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
},
33 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ZERO
,
34 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
},
37 PIPE_BLENDFACTOR_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
,
38 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
41 PIPE_BLENDFACTOR_INV_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
42 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
45 PIPE_BLENDFACTOR_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
46 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
49 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ONE
,
50 PIPE_BLENDFACTOR_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
},
53 PIPE_BLENDFACTOR_INV_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
54 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
57 PIPE_BLENDFACTOR_ZERO
, PIPE_BLENDFACTOR_ONE
,
58 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
61 PIPE_BLENDFACTOR_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
62 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
65 PIPE_BLENDFACTOR_INV_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
66 PIPE_BLENDFACTOR_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
69 PIPE_BLENDFACTOR_INV_DST_ALPHA
, PIPE_BLENDFACTOR_ONE
,
70 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
},
73 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
,
74 PIPE_BLENDFACTOR_ONE
, PIPE_BLENDFACTOR_ONE
},
79 pixel_to_float4(Pixel pixel
, float *color
)
83 a
= (pixel
>> 24) & 0xff;
84 r
= (pixel
>> 16) & 0xff;
85 g
= (pixel
>> 8) & 0xff;
86 b
= (pixel
>> 0) & 0xff;
87 color
[0] = ((float)r
) / 255.;
88 color
[1] = ((float)g
) / 255.;
89 color
[2] = ((float)b
) / 255.;
90 color
[3] = ((float)a
) / 255.;
93 struct acceleration_info
{
96 int component_alpha
: 1;
98 static const struct acceleration_info accelerated_ops
[] = {
103 {PictOpOverReverse
, 1, 0},
105 {PictOpInReverse
, 1, 0},
107 {PictOpOutReverse
, 1, 0},
109 {PictOpAtopReverse
, 1, 0},
112 {PictOpSaturate
, 1, 0},
115 static struct xorg_composite_blend
118 const int num_blends
=
119 sizeof(xorg_blends
)/sizeof(struct xorg_composite_blend
);
122 for (i
= 0; i
< num_blends
; ++i
) {
123 if (xorg_blends
[i
].op
== op
)
124 return xorg_blends
[i
];
126 return xorg_blends
[BLEND_OP_OVER
];
130 render_repeat_to_gallium(int mode
)
134 return PIPE_TEX_WRAP_CLAMP
;
136 return PIPE_TEX_WRAP_REPEAT
;
138 return PIPE_TEX_WRAP_MIRROR_REPEAT
;
140 return PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
142 debug_printf("Unsupported repeat mode\n");
144 return PIPE_TEX_WRAP_REPEAT
;
147 boolean
xorg_composite_accelerated(int op
,
148 PicturePtr pSrcPicture
,
149 PicturePtr pMaskPicture
,
150 PicturePtr pDstPicture
)
152 ScreenPtr pScreen
= pDstPicture
->pDrawable
->pScreen
;
153 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
154 modesettingPtr ms
= modesettingPTR(pScrn
);
156 unsigned accel_ops_count
=
157 sizeof(accelerated_ops
)/sizeof(struct acceleration_info
);
159 if (pSrcPicture
->pSourcePict
) {
160 if (pSrcPicture
->pSourcePict
->type
!= SourcePictTypeSolidFill
)
161 XORG_FALLBACK("gradients not enabled (haven't been well tested)");
164 for (i
= 0; i
< accel_ops_count
; ++i
) {
165 if (op
== accelerated_ops
[i
].op
) {
166 /* Check for unsupported component alpha */
167 if ((pSrcPicture
->componentAlpha
&&
168 !accelerated_ops
[i
].component_alpha
) ||
170 (!accelerated_ops
[i
].with_mask
||
171 (pMaskPicture
->componentAlpha
&&
172 !accelerated_ops
[i
].component_alpha
))))
173 XORG_FALLBACK("component alpha unsupported (PictOpOver=%s(%d)",
174 (accelerated_ops
[i
].op
== PictOpOver
) ? "yes" : "no",
175 accelerated_ops
[i
].op
);
179 XORG_FALLBACK("unsupported operation");
183 bind_blend_state(struct exa_context
*exa
, int op
,
184 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
)
186 struct xorg_composite_blend blend_opt
;
187 struct pipe_blend_state blend
;
189 blend_opt
= blend_for_op(op
);
191 memset(&blend
, 0, sizeof(struct pipe_blend_state
));
192 blend
.blend_enable
= 1;
193 blend
.colormask
|= PIPE_MASK_RGBA
;
195 blend
.rgb_src_factor
= blend_opt
.rgb_src_factor
;
196 blend
.alpha_src_factor
= blend_opt
.alpha_src_factor
;
197 blend
.rgb_dst_factor
= blend_opt
.rgb_dst_factor
;
198 blend
.alpha_dst_factor
= blend_opt
.alpha_dst_factor
;
200 cso_set_blend(exa
->renderer
->cso
, &blend
);
205 bind_shaders(struct exa_context
*exa
, int op
,
206 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
)
208 unsigned vs_traits
= 0, fs_traits
= 0;
209 struct xorg_shader shader
;
211 exa
->has_solid_color
= FALSE
;
214 if (pSrcPicture
->pSourcePict
) {
215 if (pSrcPicture
->pSourcePict
->type
== SourcePictTypeSolidFill
) {
216 fs_traits
|= FS_SOLID_FILL
;
217 vs_traits
|= VS_SOLID_FILL
;
218 debug_assert(pSrcPicture
->format
== PICT_a8r8g8b8
);
219 pixel_to_float4(pSrcPicture
->pSourcePict
->solidFill
.color
,
221 exa
->has_solid_color
= TRUE
;
223 debug_assert("!gradients not supported");
226 fs_traits
|= FS_COMPOSITE
;
227 vs_traits
|= VS_COMPOSITE
;
232 vs_traits
|= VS_MASK
;
233 fs_traits
|= FS_MASK
;
236 shader
= xorg_shaders_get(exa
->renderer
->shaders
, vs_traits
, fs_traits
);
237 cso_set_vertex_shader_handle(exa
->renderer
->cso
, shader
.vs
);
238 cso_set_fragment_shader_handle(exa
->renderer
->cso
, shader
.fs
);
243 bind_samplers(struct exa_context
*exa
, int op
,
244 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
245 PicturePtr pDstPicture
,
246 struct exa_pixmap_priv
*pSrc
,
247 struct exa_pixmap_priv
*pMask
,
248 struct exa_pixmap_priv
*pDst
)
250 struct pipe_sampler_state
*samplers
[PIPE_MAX_SAMPLERS
];
251 struct pipe_sampler_state src_sampler
, mask_sampler
;
253 exa
->num_bound_samplers
= 0;
255 memset(&src_sampler
, 0, sizeof(struct pipe_sampler_state
));
256 memset(&mask_sampler
, 0, sizeof(struct pipe_sampler_state
));
258 if ((pSrc
&& exa
->pipe
->is_texture_referenced(exa
->pipe
, pSrc
->tex
, 0, 0) &
259 PIPE_REFERENCED_FOR_WRITE
) ||
260 (pMask
&& exa
->pipe
->is_texture_referenced(exa
->pipe
, pMask
->tex
, 0, 0) &
261 PIPE_REFERENCED_FOR_WRITE
))
262 exa
->pipe
->flush(exa
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
264 if (pSrcPicture
&& pSrc
) {
265 unsigned src_wrap
= render_repeat_to_gallium(
266 pSrcPicture
->repeatType
);
267 src_sampler
.wrap_s
= src_wrap
;
268 src_sampler
.wrap_t
= src_wrap
;
269 src_sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
270 src_sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
271 src_sampler
.normalized_coords
= 1;
272 samplers
[0] = &src_sampler
;
273 exa
->bound_textures
[0] = pSrc
->tex
;
274 ++exa
->num_bound_samplers
;
277 if (pMaskPicture
&& pMask
) {
278 unsigned mask_wrap
= render_repeat_to_gallium(
279 pMaskPicture
->repeatType
);
280 mask_sampler
.wrap_s
= mask_wrap
;
281 mask_sampler
.wrap_t
= mask_wrap
;
282 mask_sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
283 mask_sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
284 mask_sampler
.normalized_coords
= 1;
285 samplers
[1] = &mask_sampler
;
286 exa
->bound_textures
[1] = pMask
->tex
;
287 ++exa
->num_bound_samplers
;
290 cso_set_samplers(exa
->renderer
->cso
, exa
->num_bound_samplers
,
291 (const struct pipe_sampler_state
**)samplers
);
292 cso_set_sampler_textures(exa
->renderer
->cso
, exa
->num_bound_samplers
,
293 exa
->bound_textures
);
297 setup_vs_constant_buffer(struct exa_context
*exa
,
298 int width
, int height
)
300 const int param_bytes
= 8 * sizeof(float);
301 float vs_consts
[8] = {
302 2.f
/width
, 2.f
/height
, 1, 1,
305 renderer_set_constants(exa
->renderer
, PIPE_SHADER_VERTEX
,
306 vs_consts
, param_bytes
);
311 setup_fs_constant_buffer(struct exa_context
*exa
)
313 const int param_bytes
= 4 * sizeof(float);
314 const float fs_consts
[8] = {
317 renderer_set_constants(exa
->renderer
, PIPE_SHADER_FRAGMENT
,
318 fs_consts
, param_bytes
);
322 setup_constant_buffers(struct exa_context
*exa
, struct exa_pixmap_priv
*pDst
)
324 int width
= pDst
->tex
->width
[0];
325 int height
= pDst
->tex
->height
[0];
327 setup_vs_constant_buffer(exa
, width
, height
);
328 setup_fs_constant_buffer(exa
);
331 boolean
xorg_composite_bind_state(struct exa_context
*exa
,
333 PicturePtr pSrcPicture
,
334 PicturePtr pMaskPicture
,
335 PicturePtr pDstPicture
,
336 struct exa_pixmap_priv
*pSrc
,
337 struct exa_pixmap_priv
*pMask
,
338 struct exa_pixmap_priv
*pDst
)
340 renderer_bind_framebuffer(exa
->renderer
, pDst
);
341 renderer_bind_viewport(exa
->renderer
, pDst
);
342 bind_blend_state(exa
, op
, pSrcPicture
, pMaskPicture
);
343 renderer_bind_rasterizer(exa
->renderer
);
344 bind_shaders(exa
, op
, pSrcPicture
, pMaskPicture
);
345 bind_samplers(exa
, op
, pSrcPicture
, pMaskPicture
,
346 pDstPicture
, pSrc
, pMask
, pDst
);
347 setup_constant_buffers(exa
, pDst
);
352 void xorg_composite(struct exa_context
*exa
,
353 struct exa_pixmap_priv
*dst
,
354 int srcX
, int srcY
, int maskX
, int maskY
,
355 int dstX
, int dstY
, int width
, int height
)
357 if (exa
->num_bound_samplers
== 0 ) { /* solid fill */
358 renderer_draw_solid_rect(exa
->renderer
,
359 dstX
, dstY
, dstX
+ width
, dstY
+ height
,
362 int pos
[6] = {srcX
, srcY
, maskX
, maskY
, dstX
, dstY
};
363 renderer_draw_textures(exa
->renderer
,
366 exa
->num_bound_samplers
);
370 boolean
xorg_solid_bind_state(struct exa_context
*exa
,
371 struct exa_pixmap_priv
*pixmap
,
374 unsigned vs_traits
, fs_traits
;
375 struct xorg_shader shader
;
377 pixel_to_float4(fg
, exa
->solid_color
);
378 exa
->has_solid_color
= TRUE
;
381 debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
382 (fg
>> 24) & 0xff, (fg
>> 16) & 0xff,
383 (fg
>> 8) & 0xff, (fg
>> 0) & 0xff,
384 exa
->solid_color
[0], exa
->solid_color
[1],
385 exa
->solid_color
[2], exa
->solid_color
[3]);
388 vs_traits
= VS_SOLID_FILL
;
389 fs_traits
= FS_SOLID_FILL
;
391 renderer_bind_framebuffer(exa
->renderer
, pixmap
);
392 renderer_bind_viewport(exa
->renderer
, pixmap
);
393 renderer_bind_rasterizer(exa
->renderer
);
394 bind_blend_state(exa
, PictOpSrc
, NULL
, NULL
);
395 setup_constant_buffers(exa
, pixmap
);
397 shader
= xorg_shaders_get(exa
->renderer
->shaders
, vs_traits
, fs_traits
);
398 cso_set_vertex_shader_handle(exa
->renderer
->cso
, shader
.vs
);
399 cso_set_fragment_shader_handle(exa
->renderer
->cso
, shader
.fs
);
404 void xorg_solid(struct exa_context
*exa
,
405 struct exa_pixmap_priv
*pixmap
,
406 int x0
, int y0
, int x1
, int y1
)
408 renderer_draw_solid_rect(exa
->renderer
,
409 x0
, y0
, x1
, y1
, exa
->solid_color
);