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 },
45 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
46 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
49 PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
50 PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
55 pixel_to_float4(Pixel pixel, float *color)
59 a = (pixel >> 24) & 0xff;
60 r = (pixel >> 16) & 0xff;
61 g = (pixel >> 8) & 0xff;
62 b = (pixel >> 0) & 0xff;
63 color[0] = ((float)r) / 255.;
64 color[1] = ((float)g) / 255.;
65 color[2] = ((float)b) / 255.;
66 color[3] = ((float)a) / 255.;
69 struct acceleration_info {
72 int component_alpha : 1;
74 static const struct acceleration_info accelerated_ops[] = {
79 {PictOpOverReverse, 1, 0},
81 {PictOpInReverse, 1, 0},
83 {PictOpOutReverse, 1, 0},
85 {PictOpAtopReverse, 1, 0},
88 {PictOpSaturate, 1, 0},
91 static struct xorg_composite_blend
94 const int num_blends =
95 sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
98 for (i = 0; i < num_blends; ++i) {
99 if (xorg_blends[i].op == op)
100 return xorg_blends[i];
102 return xorg_blends[BLEND_OP_OVER];
106 render_repeat_to_gallium(int mode)
110 return PIPE_TEX_WRAP_CLAMP;
112 return PIPE_TEX_WRAP_REPEAT;
114 return PIPE_TEX_WRAP_MIRROR_REPEAT;
116 return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
118 debug_printf("Unsupported repeat mode\n");
120 return PIPE_TEX_WRAP_REPEAT;
123 boolean xorg_composite_accelerated(int op,
124 PicturePtr pSrcPicture,
125 PicturePtr pMaskPicture,
126 PicturePtr pDstPicture)
128 ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
129 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
130 modesettingPtr ms = modesettingPTR(pScrn);
132 unsigned accel_ops_count =
133 sizeof(accelerated_ops)/sizeof(struct acceleration_info);
135 if (pSrcPicture->pSourcePict) {
136 if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
137 XORG_FALLBACK("gradients not enabled (haven't been well tested)");
140 for (i = 0; i < accel_ops_count; ++i) {
141 if (op == accelerated_ops[i].op) {
142 /* Check for unsupported component alpha */
143 if ((pSrcPicture->componentAlpha &&
144 !accelerated_ops[i].component_alpha) ||
146 (!accelerated_ops[i].with_mask ||
147 (pMaskPicture->componentAlpha &&
148 !accelerated_ops[i].component_alpha))))
149 XORG_FALLBACK("component alpha unsupported (PictOpOver=%s(%d)",
150 (accelerated_ops[i].op == PictOpOver) ? "yes" : "no",
151 accelerated_ops[i].op);
155 XORG_FALLBACK("unsupported operation");
159 bind_blend_state(struct exa_context *exa, int op,
160 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
162 struct xorg_composite_blend blend_opt;
163 struct pipe_blend_state blend;
165 blend_opt = blend_for_op(op);
167 memset(&blend, 0, sizeof(struct pipe_blend_state));
168 blend.blend_enable = 1;
169 blend.colormask |= PIPE_MASK_RGBA;
171 blend.rgb_src_factor = blend_opt.rgb_src_factor;
172 blend.alpha_src_factor = blend_opt.alpha_src_factor;
173 blend.rgb_dst_factor = blend_opt.rgb_dst_factor;
174 blend.alpha_dst_factor = blend_opt.alpha_dst_factor;
176 cso_set_blend(exa->renderer->cso, &blend);
181 bind_shaders(struct exa_context *exa, int op,
182 PicturePtr pSrcPicture, PicturePtr pMaskPicture)
184 unsigned vs_traits = 0, fs_traits = 0;
185 struct xorg_shader shader;
187 exa->has_solid_color = FALSE;
190 if (pSrcPicture->pSourcePict) {
191 if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
192 fs_traits |= FS_SOLID_FILL;
193 vs_traits |= VS_SOLID_FILL;
194 debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
195 pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
197 exa->has_solid_color = TRUE;
199 debug_assert("!gradients not supported");
202 fs_traits |= FS_COMPOSITE;
203 vs_traits |= VS_COMPOSITE;
208 vs_traits |= VS_MASK;
209 fs_traits |= FS_MASK;
212 shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
213 cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
214 cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
219 bind_samplers(struct exa_context *exa, int op,
220 PicturePtr pSrcPicture, PicturePtr pMaskPicture,
221 PicturePtr pDstPicture,
222 struct exa_pixmap_priv *pSrc,
223 struct exa_pixmap_priv *pMask,
224 struct exa_pixmap_priv *pDst)
226 struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
227 struct pipe_sampler_state src_sampler, mask_sampler;
229 exa->num_bound_samplers = 0;
231 memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
232 memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
234 if ((pSrc && exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
235 PIPE_REFERENCED_FOR_WRITE) ||
236 (pMask && exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
237 PIPE_REFERENCED_FOR_WRITE))
238 exa->pipe->flush(exa->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
240 if (pSrcPicture && pSrc) {
241 unsigned src_wrap = render_repeat_to_gallium(
242 pSrcPicture->repeatType);
243 src_sampler.wrap_s = src_wrap;
244 src_sampler.wrap_t = src_wrap;
245 src_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
246 src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
247 src_sampler.normalized_coords = 1;
248 samplers[0] = &src_sampler;
249 exa->bound_textures[0] = pSrc->tex;
250 ++exa->num_bound_samplers;
253 if (pMaskPicture && pMask) {
254 unsigned mask_wrap = render_repeat_to_gallium(
255 pMaskPicture->repeatType);
256 mask_sampler.wrap_s = mask_wrap;
257 mask_sampler.wrap_t = mask_wrap;
258 mask_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
259 mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
260 mask_sampler.normalized_coords = 1;
261 samplers[1] = &mask_sampler;
262 exa->bound_textures[1] = pMask->tex;
263 ++exa->num_bound_samplers;
266 cso_set_samplers(exa->renderer->cso, exa->num_bound_samplers,
267 (const struct pipe_sampler_state **)samplers);
268 cso_set_sampler_textures(exa->renderer->cso, exa->num_bound_samplers,
269 exa->bound_textures);
273 setup_vs_constant_buffer(struct exa_context *exa,
274 int width, int height)
276 const int param_bytes = 8 * sizeof(float);
277 float vs_consts[8] = {
278 2.f/width, 2.f/height, 1, 1,
281 renderer_set_constants(exa->renderer, PIPE_SHADER_VERTEX,
282 vs_consts, param_bytes);
287 setup_fs_constant_buffer(struct exa_context *exa)
289 const int param_bytes = 4 * sizeof(float);
290 const float fs_consts[8] = {
293 renderer_set_constants(exa->renderer, PIPE_SHADER_FRAGMENT,
294 fs_consts, param_bytes);
298 setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
300 int width = pDst->tex->width[0];
301 int height = pDst->tex->height[0];
303 setup_vs_constant_buffer(exa, width, height);
304 setup_fs_constant_buffer(exa);
307 boolean xorg_composite_bind_state(struct exa_context *exa,
309 PicturePtr pSrcPicture,
310 PicturePtr pMaskPicture,
311 PicturePtr pDstPicture,
312 struct exa_pixmap_priv *pSrc,
313 struct exa_pixmap_priv *pMask,
314 struct exa_pixmap_priv *pDst)
316 renderer_bind_framebuffer(exa->renderer, pDst);
317 renderer_bind_viewport(exa->renderer, pDst);
318 bind_blend_state(exa, op, pSrcPicture, pMaskPicture);
319 renderer_bind_rasterizer(exa->renderer);
320 bind_shaders(exa, op, pSrcPicture, pMaskPicture);
321 bind_samplers(exa, op, pSrcPicture, pMaskPicture,
322 pDstPicture, pSrc, pMask, pDst);
323 setup_constant_buffers(exa, pDst);
328 void xorg_composite(struct exa_context *exa,
329 struct exa_pixmap_priv *dst,
330 int srcX, int srcY, int maskX, int maskY,
331 int dstX, int dstY, int width, int height)
333 if (exa->num_bound_samplers == 0 ) { /* solid fill */
334 renderer_draw_solid_rect(exa->renderer,
335 dstX, dstY, dstX + width, dstY + height,
338 int pos[6] = {srcX, srcY, maskX, maskY, dstX, dstY};
339 renderer_draw_textures(exa->renderer,
342 exa->num_bound_samplers);
346 boolean xorg_solid_bind_state(struct exa_context *exa,
347 struct exa_pixmap_priv *pixmap,
350 unsigned vs_traits, fs_traits;
351 struct xorg_shader shader;
353 pixel_to_float4(fg, exa->solid_color);
354 exa->has_solid_color = TRUE;
357 debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
358 (fg >> 24) & 0xff, (fg >> 16) & 0xff,
359 (fg >> 8) & 0xff, (fg >> 0) & 0xff,
360 exa->solid_color[0], exa->solid_color[1],
361 exa->solid_color[2], exa->solid_color[3]);
364 vs_traits = VS_SOLID_FILL;
365 fs_traits = FS_SOLID_FILL;
367 renderer_bind_framebuffer(exa->renderer, pixmap);
368 renderer_bind_viewport(exa->renderer, pixmap);
369 renderer_bind_rasterizer(exa->renderer);
370 bind_blend_state(exa, PictOpSrc, NULL, NULL);
371 setup_constant_buffers(exa, pixmap);
373 shader = xorg_shaders_get(exa->renderer->shaders, vs_traits, fs_traits);
374 cso_set_vertex_shader_handle(exa->renderer->cso, shader.vs);
375 cso_set_fragment_shader_handle(exa->renderer->cso, shader.fs);
380 void xorg_solid(struct exa_context *exa,
381 struct exa_pixmap_priv *pixmap,
382 int x0, int y0, int x1, int y1)
384 renderer_draw_solid_rect(exa->renderer,
385 x0, y0, x1, y1, exa->solid_color);