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_CONST_COLOR
, PIPE_BLENDFACTOR_CONST_ALPHA
,
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_SRC_ALPHA
, PIPE_BLENDFACTOR_ONE
,
42 PIPE_BLENDFACTOR_INV_SRC_ALPHA
, PIPE_BLENDFACTOR_INV_SRC_ALPHA
},
47 pixel_to_float4(Pixel pixel
, float *color
)
51 a
= (pixel
>> 24) & 0xff;
52 r
= (pixel
>> 16) & 0xff;
53 g
= (pixel
>> 8) & 0xff;
54 b
= (pixel
>> 0) & 0xff;
55 color
[0] = ((float)r
) / 255.;
56 color
[1] = ((float)g
) / 255.;
57 color
[2] = ((float)b
) / 255.;
58 color
[3] = ((float)a
) / 255.;
61 struct acceleration_info
{
64 int component_alpha
: 1;
66 static const struct acceleration_info accelerated_ops
[] = {
71 {PictOpOverReverse
, 1, 0},
73 {PictOpInReverse
, 1, 0},
75 {PictOpOutReverse
, 1, 0},
77 {PictOpAtopReverse
, 1, 0},
80 {PictOpSaturate
, 1, 0},
83 static struct xorg_composite_blend
86 const int num_blends
=
87 sizeof(xorg_blends
)/sizeof(struct xorg_composite_blend
);
90 for (i
= 0; i
< num_blends
; ++i
) {
91 if (xorg_blends
[i
].op
== op
)
92 return xorg_blends
[i
];
94 return xorg_blends
[BLEND_OP_OVER
];
98 render_repeat_to_gallium(int mode
)
102 return PIPE_TEX_WRAP_CLAMP
;
104 return PIPE_TEX_WRAP_REPEAT
;
106 return PIPE_TEX_WRAP_MIRROR_REPEAT
;
108 return PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
110 debug_printf("Unsupported repeat mode\n");
112 return PIPE_TEX_WRAP_REPEAT
;
115 boolean
xorg_composite_accelerated(int op
,
116 PicturePtr pSrcPicture
,
117 PicturePtr pMaskPicture
,
118 PicturePtr pDstPicture
)
120 ScreenPtr pScreen
= pDstPicture
->pDrawable
->pScreen
;
121 ScrnInfoPtr pScrn
= xf86Screens
[pScreen
->myNum
];
122 modesettingPtr ms
= modesettingPTR(pScrn
);
124 unsigned accel_ops_count
=
125 sizeof(accelerated_ops
)/sizeof(struct acceleration_info
);
127 if (pSrcPicture
->pSourcePict
) {
128 if (pSrcPicture
->pSourcePict
->type
!= SourcePictTypeSolidFill
)
129 XORG_FALLBACK("gradients not enabled (haven't been well tested)");
132 for (i
= 0; i
< accel_ops_count
; ++i
) {
133 if (op
== accelerated_ops
[i
].op
) {
134 /* Check for unsupported component alpha */
135 if ((pSrcPicture
->componentAlpha
&&
136 !accelerated_ops
[i
].component_alpha
) ||
138 (!accelerated_ops
[i
].with_mask
||
139 (pMaskPicture
->componentAlpha
&&
140 !accelerated_ops
[i
].component_alpha
))))
141 XORG_FALLBACK("component alpha unsupported");
145 XORG_FALLBACK("unsupported operation");
149 bind_blend_state(struct exa_context
*exa
, int op
,
150 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
)
152 struct xorg_composite_blend blend_opt
;
153 struct pipe_blend_state blend
;
155 blend_opt
= blend_for_op(op
);
157 memset(&blend
, 0, sizeof(struct pipe_blend_state
));
158 blend
.blend_enable
= 1;
159 blend
.colormask
|= PIPE_MASK_R
;
160 blend
.colormask
|= PIPE_MASK_G
;
161 blend
.colormask
|= PIPE_MASK_B
;
162 blend
.colormask
|= PIPE_MASK_A
;
164 blend
.rgb_src_factor
= blend_opt
.rgb_src_factor
;
165 blend
.alpha_src_factor
= blend_opt
.alpha_src_factor
;
166 blend
.rgb_dst_factor
= blend_opt
.rgb_dst_factor
;
167 blend
.alpha_dst_factor
= blend_opt
.alpha_dst_factor
;
169 cso_set_blend(exa
->renderer
->cso
, &blend
);
174 bind_shaders(struct exa_context
*exa
, int op
,
175 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
)
177 unsigned vs_traits
= 0, fs_traits
= 0;
178 struct xorg_shader shader
;
180 exa
->has_solid_color
= FALSE
;
183 if (pSrcPicture
->pSourcePict
) {
184 if (pSrcPicture
->pSourcePict
->type
== SourcePictTypeSolidFill
) {
185 fs_traits
|= FS_SOLID_FILL
;
186 vs_traits
|= VS_SOLID_FILL
;
187 debug_assert(pSrcPicture
->format
== PICT_a8r8g8b8
);
188 pixel_to_float4(pSrcPicture
->pSourcePict
->solidFill
.color
,
190 exa
->has_solid_color
= TRUE
;
192 debug_assert("!gradients not supported");
195 fs_traits
|= FS_COMPOSITE
;
196 vs_traits
|= VS_COMPOSITE
;
201 vs_traits
|= VS_MASK
;
202 fs_traits
|= FS_MASK
;
205 shader
= xorg_shaders_get(exa
->renderer
->shaders
, vs_traits
, fs_traits
);
206 cso_set_vertex_shader_handle(exa
->renderer
->cso
, shader
.vs
);
207 cso_set_fragment_shader_handle(exa
->renderer
->cso
, shader
.fs
);
212 bind_samplers(struct exa_context
*exa
, int op
,
213 PicturePtr pSrcPicture
, PicturePtr pMaskPicture
,
214 PicturePtr pDstPicture
,
215 struct exa_pixmap_priv
*pSrc
,
216 struct exa_pixmap_priv
*pMask
,
217 struct exa_pixmap_priv
*pDst
)
219 struct pipe_sampler_state
*samplers
[PIPE_MAX_SAMPLERS
];
220 struct pipe_sampler_state src_sampler
, mask_sampler
;
222 exa
->num_bound_samplers
= 0;
224 memset(&src_sampler
, 0, sizeof(struct pipe_sampler_state
));
225 memset(&mask_sampler
, 0, sizeof(struct pipe_sampler_state
));
227 if ((pSrc
&& exa
->pipe
->is_texture_referenced(exa
->pipe
, pSrc
->tex
, 0, 0) &
228 PIPE_REFERENCED_FOR_WRITE
) ||
229 (pMask
&& exa
->pipe
->is_texture_referenced(exa
->pipe
, pMask
->tex
, 0, 0) &
230 PIPE_REFERENCED_FOR_WRITE
))
231 exa
->pipe
->flush(exa
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
233 if (pSrcPicture
&& pSrc
) {
234 unsigned src_wrap
= render_repeat_to_gallium(
235 pSrcPicture
->repeatType
);
236 src_sampler
.wrap_s
= src_wrap
;
237 src_sampler
.wrap_t
= src_wrap
;
238 src_sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
239 src_sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
240 src_sampler
.normalized_coords
= 1;
241 samplers
[0] = &src_sampler
;
242 exa
->bound_textures
[0] = pSrc
->tex
;
243 ++exa
->num_bound_samplers
;
246 if (pMaskPicture
&& pMask
) {
247 unsigned mask_wrap
= render_repeat_to_gallium(
248 pMaskPicture
->repeatType
);
249 mask_sampler
.wrap_s
= mask_wrap
;
250 mask_sampler
.wrap_t
= mask_wrap
;
251 mask_sampler
.min_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
252 mask_sampler
.mag_img_filter
= PIPE_TEX_MIPFILTER_NEAREST
;
253 mask_sampler
.normalized_coords
= 1;
254 samplers
[1] = &mask_sampler
;
255 exa
->bound_textures
[1] = pMask
->tex
;
256 ++exa
->num_bound_samplers
;
259 cso_set_samplers(exa
->renderer
->cso
, exa
->num_bound_samplers
,
260 (const struct pipe_sampler_state
**)samplers
);
261 cso_set_sampler_textures(exa
->renderer
->cso
, exa
->num_bound_samplers
,
262 exa
->bound_textures
);
266 setup_vs_constant_buffer(struct exa_context
*exa
,
267 int width
, int height
)
269 const int param_bytes
= 8 * sizeof(float);
270 float vs_consts
[8] = {
271 2.f
/width
, 2.f
/height
, 1, 1,
274 renderer_set_constants(exa
->renderer
, PIPE_SHADER_VERTEX
,
275 vs_consts
, param_bytes
);
280 setup_fs_constant_buffer(struct exa_context
*exa
)
282 const int param_bytes
= 4 * sizeof(float);
283 const float fs_consts
[8] = {
286 renderer_set_constants(exa
->renderer
, PIPE_SHADER_FRAGMENT
,
287 fs_consts
, param_bytes
);
291 setup_constant_buffers(struct exa_context
*exa
, struct exa_pixmap_priv
*pDst
)
293 int width
= pDst
->tex
->width
[0];
294 int height
= pDst
->tex
->height
[0];
296 setup_vs_constant_buffer(exa
, width
, height
);
297 setup_fs_constant_buffer(exa
);
300 boolean
xorg_composite_bind_state(struct exa_context
*exa
,
302 PicturePtr pSrcPicture
,
303 PicturePtr pMaskPicture
,
304 PicturePtr pDstPicture
,
305 struct exa_pixmap_priv
*pSrc
,
306 struct exa_pixmap_priv
*pMask
,
307 struct exa_pixmap_priv
*pDst
)
309 renderer_bind_framebuffer(exa
->renderer
, pDst
);
310 renderer_bind_viewport(exa
->renderer
, pDst
);
311 bind_blend_state(exa
, op
, pSrcPicture
, pMaskPicture
);
312 renderer_bind_rasterizer(exa
->renderer
);
313 bind_shaders(exa
, op
, pSrcPicture
, pMaskPicture
);
314 bind_samplers(exa
, op
, pSrcPicture
, pMaskPicture
,
315 pDstPicture
, pSrc
, pMask
, pDst
);
316 setup_constant_buffers(exa
, pDst
);
321 void xorg_composite(struct exa_context
*exa
,
322 struct exa_pixmap_priv
*dst
,
323 int srcX
, int srcY
, int maskX
, int maskY
,
324 int dstX
, int dstY
, int width
, int height
)
326 if (exa
->num_bound_samplers
== 0 ) { /* solid fill */
327 renderer_draw_solid_rect(exa
->renderer
,
328 dstX
, dstY
, dstX
+ width
, dstY
+ height
,
331 int pos
[6] = {srcX
, srcY
, maskX
, maskY
, dstX
, dstY
};
332 renderer_draw_textures(exa
->renderer
,
335 exa
->num_bound_samplers
);
339 boolean
xorg_solid_bind_state(struct exa_context
*exa
,
340 struct exa_pixmap_priv
*pixmap
,
343 unsigned vs_traits
, fs_traits
;
344 struct xorg_shader shader
;
346 pixel_to_float4(fg
, exa
->solid_color
);
347 exa
->has_solid_color
= TRUE
;
349 exa
->solid_color
[3] = 1.f
;
352 debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
353 (fg
>> 24) & 0xff, (fg
>> 16) & 0xff,
354 (fg
>> 8) & 0xff, (fg
>> 0) & 0xff,
355 exa
->solid_color
[0], exa
->solid_color
[1],
356 exa
->solid_color
[2], exa
->solid_color
[3]);
359 vs_traits
= VS_SOLID_FILL
;
360 fs_traits
= FS_SOLID_FILL
;
362 renderer_bind_framebuffer(exa
->renderer
, pixmap
);
363 renderer_bind_viewport(exa
->renderer
, pixmap
);
364 renderer_bind_rasterizer(exa
->renderer
);
365 bind_blend_state(exa
, PictOpSrc
, NULL
, NULL
);
366 setup_constant_buffers(exa
, pixmap
);
368 shader
= xorg_shaders_get(exa
->renderer
->shaders
, vs_traits
, fs_traits
);
369 cso_set_vertex_shader_handle(exa
->renderer
->cso
, shader
.vs
);
370 cso_set_fragment_shader_handle(exa
->renderer
->cso
, shader
.fs
);
375 void xorg_solid(struct exa_context
*exa
,
376 struct exa_pixmap_priv
*pixmap
,
377 int x0
, int y0
, int x1
, int y1
)
379 renderer_draw_solid_rect(exa
->renderer
,
380 x0
, y0
, x1
, y1
, exa
->solid_color
);