2 #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"
9 #include "util/u_memory.h"
10 #include "util/u_rect.h"
12 #include "pipe/p_inlines.h"
16 enum AxisOrientation
{
21 #define floatsEqual(x, y) (fabs(x - y) <= 0.00001f * MIN2(fabs(x), fabs(y)))
22 #define floatIsZero(x) (floatsEqual((x) + 1, 1))
24 static INLINE boolean
is_affine(float *matrix
)
26 return floatIsZero(matrix
[2]) && floatIsZero(matrix
[5])
27 && floatsEqual(matrix
[8], 1);
29 static INLINE
void map_point(float *mat
, float x
, float y
,
30 float *out_x
, float *out_y
)
38 *out_x
= mat
[0]*x
+ mat
[3]*y
+ mat
[6];
39 *out_y
= mat
[1]*x
+ mat
[4]*y
+ mat
[7];
40 if (!is_affine(mat
)) {
41 float w
= 1/(mat
[2]*x
+ mat
[5]*y
+ mat
[8]);
48 renderer_init_state(struct xorg_renderer
*r
)
50 struct pipe_depth_stencil_alpha_state dsa
;
52 /* set common initial clip state */
53 memset(&dsa
, 0, sizeof(struct pipe_depth_stencil_alpha_state
));
54 cso_set_depth_stencil_alpha(r
->cso
, &dsa
);
59 setup_vertex0(float vertex
[2][4], float x
, float y
,
64 vertex
[0][2] = 0.f
; /*z*/
65 vertex
[0][3] = 1.f
; /*w*/
67 vertex
[1][0] = color
[0]; /*r*/
68 vertex
[1][1] = color
[1]; /*g*/
69 vertex
[1][2] = color
[2]; /*b*/
70 vertex
[1][3] = color
[3]; /*a*/
74 setup_vertex1(float vertex
[2][4], float x
, float y
, float s
, float t
)
78 vertex
[0][2] = 0.f
; /*z*/
79 vertex
[0][3] = 1.f
; /*w*/
81 vertex
[1][0] = s
; /*s*/
82 vertex
[1][1] = t
; /*t*/
83 vertex
[1][2] = 0.f
; /*r*/
84 vertex
[1][3] = 1.f
; /*q*/
87 static struct pipe_buffer
*
88 setup_vertex_data1(struct xorg_renderer
*r
,
89 float srcX
, float srcY
, float dstX
, float dstY
,
90 float width
, float height
,
91 struct pipe_texture
*src
, float *src_matrix
)
98 pt1
[0] = (srcX
+ width
);
99 pt1
[1] = (srcY
+ height
);
102 map_point(src_matrix
, pt0
[0], pt0
[1], &pt0
[0], &pt0
[1]);
103 map_point(src_matrix
, pt1
[0], pt1
[1], &pt1
[0], &pt1
[1]);
106 s0
= pt0
[0] / src
->width
[0];
107 s1
= pt1
[0] / src
->width
[0];
108 t0
= pt0
[1] / src
->height
[0];
109 t1
= pt1
[1] / src
->height
[0];
112 setup_vertex1(r
->vertices2
[0], dstX
, dstY
, s0
, t0
);
114 setup_vertex1(r
->vertices2
[1], dstX
+ width
, dstY
, s1
, t0
);
116 setup_vertex1(r
->vertices2
[2], dstX
+ width
, dstY
+ height
, s1
, t1
);
118 setup_vertex1(r
->vertices2
[3], dstX
, dstY
+ height
, s0
, t1
);
120 return pipe_user_buffer_create(r
->pipe
->screen
,
122 sizeof(r
->vertices2
));
125 static struct pipe_buffer
*
126 setup_vertex_data_tex(struct xorg_renderer
*r
,
127 float x0
, float y0
, float x1
, float y1
,
128 float s0
, float t0
, float s1
, float t1
,
132 setup_vertex1(r
->vertices2
[0], x0
, y0
, s0
, t0
);
134 setup_vertex1(r
->vertices2
[1], x1
, y0
, s1
, t0
);
136 setup_vertex1(r
->vertices2
[2], x1
, y1
, s1
, t1
);
138 setup_vertex1(r
->vertices2
[3], x0
, y1
, s0
, t1
);
140 return pipe_user_buffer_create(r
->pipe
->screen
,
142 sizeof(r
->vertices2
));
146 setup_vertex2(float vertex
[3][4], float x
, float y
,
147 float s0
, float t0
, float s1
, float t1
)
151 vertex
[0][2] = 0.f
; /*z*/
152 vertex
[0][3] = 1.f
; /*w*/
154 vertex
[1][0] = s0
; /*s*/
155 vertex
[1][1] = t0
; /*t*/
156 vertex
[1][2] = 0.f
; /*r*/
157 vertex
[1][3] = 1.f
; /*q*/
159 vertex
[2][0] = s1
; /*s*/
160 vertex
[2][1] = t1
; /*t*/
161 vertex
[2][2] = 0.f
; /*r*/
162 vertex
[2][3] = 1.f
; /*q*/
165 static struct pipe_buffer
*
166 setup_vertex_data2(struct xorg_renderer
*r
,
167 float srcX
, float srcY
, float maskX
, float maskY
,
168 float dstX
, float dstY
, float width
, float height
,
169 struct pipe_texture
*src
,
170 struct pipe_texture
*mask
,
171 float *src_matrix
, float *mask_matrix
)
173 float src_s0
, src_t0
, src_s1
, src_t1
;
174 float mask_s0
, mask_t0
, mask_s1
, mask_t1
;
175 float spt0
[2], spt1
[2];
176 float mpt0
[2], mpt1
[2];
180 spt1
[0] = srcX
+ width
;
181 spt1
[1] = srcY
+ height
;
185 mpt1
[0] = maskX
+ width
;
186 mpt1
[1] = maskY
+ height
;
189 map_point(src_matrix
, spt0
[0], spt0
[1], &spt0
[0], &spt0
[1]);
190 map_point(src_matrix
, spt1
[0], spt1
[1], &spt1
[0], &spt1
[1]);
194 map_point(mask_matrix
, mpt0
[0], mpt0
[1], &mpt0
[0], &mpt0
[1]);
195 map_point(mask_matrix
, mpt1
[0], mpt1
[1], &mpt1
[0], &mpt1
[1]);
198 src_s0
= spt0
[0] / src
->width
[0];
199 src_t0
= spt0
[1] / src
->height
[0];
200 src_s1
= spt1
[0] / src
->width
[0];
201 src_t1
= spt1
[1] / src
->height
[0];
203 mask_s0
= mpt0
[0] / mask
->width
[0];
204 mask_t0
= mpt0
[1] / mask
->height
[0];
205 mask_s1
= mpt1
[0] / mask
->width
[0];
206 mask_t1
= mpt1
[1] / mask
->height
[0];
209 setup_vertex2(r
->vertices3
[0], dstX
, dstY
,
210 src_s0
, src_t0
, mask_s0
, mask_t0
);
212 setup_vertex2(r
->vertices3
[1], dstX
+ width
, dstY
,
213 src_s1
, src_t0
, mask_s1
, mask_t0
);
215 setup_vertex2(r
->vertices3
[2], dstX
+ width
, dstY
+ height
,
216 src_s1
, src_t1
, mask_s1
, mask_t1
);
218 setup_vertex2(r
->vertices3
[3], dstX
, dstY
+ height
,
219 src_s0
, src_t1
, mask_s0
, mask_t1
);
222 return pipe_user_buffer_create(r
->pipe
->screen
,
224 sizeof(r
->vertices3
));
227 static struct pipe_buffer
*
228 setup_vertex_data_yuv(struct xorg_renderer
*r
,
229 float srcX
, float srcY
,
230 float dstX
, float dstY
,
231 float width
, float height
,
232 struct pipe_texture
**tex
)
234 float s0
, t0
, s1
, t1
;
235 float spt0
[2], spt1
[2];
239 spt1
[0] = srcX
+ width
;
240 spt1
[1] = srcY
+ height
;
242 s0
= spt0
[0] / tex
[0]->width
[0];
243 t0
= spt0
[1] / tex
[0]->height
[0];
244 s1
= spt1
[0] / tex
[0]->width
[0];
245 t1
= spt1
[1] / tex
[0]->height
[0];
248 setup_vertex1(r
->vertices2
[0], dstX
, dstY
, s0
, t0
);
250 setup_vertex1(r
->vertices2
[1], dstX
+ width
, dstY
,
253 setup_vertex1(r
->vertices2
[2], dstX
+ width
, dstY
+ height
,
256 setup_vertex1(r
->vertices2
[3], dstX
, dstY
+ height
,
260 return pipe_user_buffer_create(r
->pipe
->screen
,
262 sizeof(r
->vertices2
));
268 set_viewport(struct xorg_renderer
*r
, int width
, int height
,
269 enum AxisOrientation orientation
)
271 struct pipe_viewport_state viewport
;
272 float y_scale
= (orientation
== Y0_BOTTOM
) ? -2.f
: 2.f
;
274 viewport
.scale
[0] = width
/ 2.f
;
275 viewport
.scale
[1] = height
/ y_scale
;
276 viewport
.scale
[2] = 1.0;
277 viewport
.scale
[3] = 1.0;
278 viewport
.translate
[0] = width
/ 2.f
;
279 viewport
.translate
[1] = height
/ 2.f
;
280 viewport
.translate
[2] = 0.0;
281 viewport
.translate
[3] = 0.0;
283 cso_set_viewport(r
->cso
, &viewport
);
288 struct xorg_renderer
* renderer_create(struct pipe_context
*pipe
)
290 struct xorg_renderer
*renderer
= CALLOC_STRUCT(xorg_renderer
);
292 renderer
->pipe
= pipe
;
293 renderer
->cso
= cso_create_context(pipe
);
294 renderer
->shaders
= xorg_shaders_create(renderer
);
296 renderer_init_state(renderer
);
301 void renderer_destroy(struct xorg_renderer
*r
)
303 struct pipe_constant_buffer
*vsbuf
= &r
->vs_const_buffer
;
304 struct pipe_constant_buffer
*fsbuf
= &r
->fs_const_buffer
;
306 if (vsbuf
&& vsbuf
->buffer
)
307 pipe_buffer_reference(&vsbuf
->buffer
, NULL
);
309 if (fsbuf
&& fsbuf
->buffer
)
310 pipe_buffer_reference(&fsbuf
->buffer
, NULL
);
313 xorg_shaders_destroy(r
->shaders
);
318 cso_release_all(r
->cso
);
319 cso_destroy_context(r
->cso
);
324 void renderer_bind_framebuffer(struct xorg_renderer
*r
,
325 struct exa_pixmap_priv
*priv
)
328 struct pipe_framebuffer_state state
;
329 struct pipe_surface
*surface
= xorg_gpu_surface(r
->pipe
->screen
, priv
);
330 memset(&state
, 0, sizeof(struct pipe_framebuffer_state
));
332 state
.width
= priv
->tex
->width
[0];
333 state
.height
= priv
->tex
->height
[0];
336 state
.cbufs
[0] = surface
;
337 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
340 /* currently we don't use depth/stencil */
343 cso_set_framebuffer(r
->cso
, &state
);
345 /* we do fire and forget for the framebuffer, this is the forget part */
346 pipe_surface_reference(&surface
, NULL
);
349 void renderer_bind_viewport(struct xorg_renderer
*r
,
350 struct exa_pixmap_priv
*dst
)
352 int width
= dst
->tex
->width
[0];
353 int height
= dst
->tex
->height
[0];
355 /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
357 set_viewport(r
, width
, height
, Y0_TOP
);
360 void renderer_bind_rasterizer(struct xorg_renderer
*r
)
362 struct pipe_rasterizer_state raster
;
364 /* XXX: move to renderer_init_state? */
365 memset(&raster
, 0, sizeof(struct pipe_rasterizer_state
));
366 raster
.gl_rasterization_rules
= 1;
367 cso_set_rasterizer(r
->cso
, &raster
);
370 void renderer_set_constants(struct xorg_renderer
*r
,
375 struct pipe_constant_buffer
*cbuf
=
376 (shader_type
== PIPE_SHADER_VERTEX
) ? &r
->vs_const_buffer
:
379 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
380 cbuf
->buffer
= pipe_buffer_create(r
->pipe
->screen
, 16,
381 PIPE_BUFFER_USAGE_CONSTANT
,
385 pipe_buffer_write(r
->pipe
->screen
, cbuf
->buffer
,
386 0, param_bytes
, params
);
388 r
->pipe
->set_constant_buffer(r
->pipe
, shader_type
, 0, cbuf
);
392 setup_vs_constant_buffer(struct xorg_renderer
*r
,
393 int width
, int height
)
395 const int param_bytes
= 8 * sizeof(float);
396 float vs_consts
[8] = {
397 2.f
/width
, 2.f
/height
, 1, 1,
400 renderer_set_constants(r
, PIPE_SHADER_VERTEX
,
401 vs_consts
, param_bytes
);
405 setup_fs_constant_buffer(struct xorg_renderer
*r
)
407 const int param_bytes
= 4 * sizeof(float);
408 const float fs_consts
[8] = {
411 renderer_set_constants(r
, PIPE_SHADER_FRAGMENT
,
412 fs_consts
, param_bytes
);
415 static INLINE
void shift_rectx(float coords
[4],
422 coords
[2] = MIN2(coords
[2], bounds
[2]);
423 /* bound x/y + width/height */
424 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
425 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
430 static INLINE
void shift_recty(float coords
[4],
437 coords
[3] = MIN2(coords
[3], bounds
[3]);
438 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
439 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
444 static INLINE
void bound_rect(float coords
[4],
445 const float bounds
[4],
448 /* if outside the bounds */
449 if (coords
[0] > (bounds
[0] + bounds
[2]) ||
450 coords
[1] > (bounds
[1] + bounds
[3]) ||
451 (coords
[0] + coords
[2]) < bounds
[0] ||
452 (coords
[1] + coords
[3]) < bounds
[1]) {
463 if (coords
[0] < bounds
[0]) {
464 shift
[0] = bounds
[0] - coords
[0];
465 coords
[2] -= shift
[0];
466 coords
[0] = bounds
[0];
471 if (coords
[1] < bounds
[1]) {
472 shift
[1] = bounds
[1] - coords
[1];
473 coords
[3] -= shift
[1];
474 coords
[1] = bounds
[1];
478 shift
[2] = bounds
[2] - coords
[2];
479 shift
[3] = bounds
[3] - coords
[3];
480 /* bound width/height */
481 coords
[2] = MIN2(coords
[2], bounds
[2]);
482 coords
[3] = MIN2(coords
[3], bounds
[3]);
484 /* bound x/y + width/height */
485 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
486 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
488 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
489 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
492 /* if outside the bounds */
493 if ((coords
[0] + coords
[2]) < bounds
[0] ||
494 (coords
[1] + coords
[3]) < bounds
[1]) {
503 static INLINE
void sync_size(float *src_loc
, float *dst_loc
)
505 src_loc
[2] = MIN2(src_loc
[2], dst_loc
[2]);
506 src_loc
[3] = MIN2(src_loc
[3], dst_loc
[3]);
507 dst_loc
[2] = src_loc
[2];
508 dst_loc
[3] = src_loc
[3];
511 static void renderer_copy_texture(struct xorg_renderer
*r
,
512 struct pipe_texture
*src
,
513 float sx1
, float sy1
,
514 float sx2
, float sy2
,
515 struct pipe_texture
*dst
,
516 float dx1
, float dy1
,
517 float dx2
, float dy2
)
519 struct pipe_context
*pipe
= r
->pipe
;
520 struct pipe_screen
*screen
= pipe
->screen
;
521 struct pipe_buffer
*buf
;
522 struct pipe_surface
*dst_surf
= screen
->get_tex_surface(
523 screen
, dst
, 0, 0, 0,
524 PIPE_BUFFER_USAGE_GPU_WRITE
);
525 struct pipe_framebuffer_state fb
;
526 float s0
, t0
, s1
, t1
;
527 struct xorg_shader shader
;
529 assert(src
->width
[0] != 0);
530 assert(src
->height
[0] != 0);
531 assert(dst
->width
[0] != 0);
532 assert(dst
->height
[0] != 0);
535 s0
= sx1
/ src
->width
[0];
536 s1
= sx2
/ src
->width
[0];
537 t0
= sy1
/ src
->height
[0];
538 t1
= sy2
/ src
->height
[0];
547 debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
548 sx1
, sy1
, sx2
, sy2
, dx1
, dy1
, dx2
, dy2
,
552 assert(screen
->is_format_supported(screen
, dst_surf
->format
,
554 PIPE_TEXTURE_USAGE_RENDER_TARGET
,
557 /* save state (restored below) */
558 cso_save_blend(r
->cso
);
559 cso_save_samplers(r
->cso
);
560 cso_save_sampler_textures(r
->cso
);
561 cso_save_framebuffer(r
->cso
);
562 cso_save_fragment_shader(r
->cso
);
563 cso_save_vertex_shader(r
->cso
);
565 cso_save_viewport(r
->cso
);
568 /* set misc state we care about */
570 struct pipe_blend_state blend
;
571 memset(&blend
, 0, sizeof(blend
));
572 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
573 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
574 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
575 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
576 blend
.colormask
= PIPE_MASK_RGBA
;
577 cso_set_blend(r
->cso
, &blend
);
582 struct pipe_sampler_state sampler
;
583 memset(&sampler
, 0, sizeof(sampler
));
584 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
585 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
586 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
587 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
588 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
589 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
590 sampler
.normalized_coords
= 1;
591 cso_single_sampler(r
->cso
, 0, &sampler
);
592 cso_single_sampler_done(r
->cso
);
595 set_viewport(r
, dst_surf
->width
, dst_surf
->height
, Y0_TOP
);
598 cso_set_sampler_textures(r
->cso
, 1, &src
);
600 renderer_bind_rasterizer(r
);
603 shader
= xorg_shaders_get(r
->shaders
,
606 cso_set_vertex_shader_handle(r
->cso
, shader
.vs
);
607 cso_set_fragment_shader_handle(r
->cso
, shader
.fs
);
610 memset(&fb
, 0, sizeof(fb
));
611 fb
.width
= dst_surf
->width
;
612 fb
.height
= dst_surf
->height
;
614 fb
.cbufs
[0] = dst_surf
;
617 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
620 cso_set_framebuffer(r
->cso
, &fb
);
621 setup_vs_constant_buffer(r
, fb
.width
, fb
.height
);
622 setup_fs_constant_buffer(r
);
625 buf
= setup_vertex_data_tex(r
,
632 util_draw_vertex_buffer(r
->pipe
, buf
, 0,
633 PIPE_PRIM_TRIANGLE_FAN
,
635 2); /* attribs/vert */
637 pipe_buffer_reference(&buf
, NULL
);
640 /* restore state we changed */
641 cso_restore_blend(r
->cso
);
642 cso_restore_samplers(r
->cso
);
643 cso_restore_sampler_textures(r
->cso
);
644 cso_restore_framebuffer(r
->cso
);
645 cso_restore_vertex_shader(r
->cso
);
646 cso_restore_fragment_shader(r
->cso
);
647 cso_restore_viewport(r
->cso
);
649 pipe_surface_reference(&dst_surf
, NULL
);
652 static struct pipe_texture
*
653 create_sampler_texture(struct xorg_renderer
*r
,
654 struct pipe_texture
*src
)
656 enum pipe_format format
;
657 struct pipe_context
*pipe
= r
->pipe
;
658 struct pipe_screen
*screen
= pipe
->screen
;
659 struct pipe_texture
*pt
;
660 struct pipe_texture templ
;
662 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
664 /* the coming in texture should already have that invariance */
665 debug_assert(screen
->is_format_supported(screen
, src
->format
,
667 PIPE_TEXTURE_USAGE_SAMPLER
, 0));
669 format
= src
->format
;
671 memset(&templ
, 0, sizeof(templ
));
672 templ
.target
= PIPE_TEXTURE_2D
;
673 templ
.format
= format
;
674 templ
.last_level
= 0;
675 templ
.width
[0] = src
->width
[0];
676 templ
.height
[0] = src
->height
[0];
678 pf_get_block(format
, &templ
.block
);
679 templ
.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
681 pt
= screen
->texture_create(screen
, &templ
);
683 debug_assert(!pt
|| pipe_is_referenced(&pt
->reference
));
689 /* copy source framebuffer surface into texture */
690 struct pipe_surface
*ps_read
= screen
->get_tex_surface(
691 screen
, src
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
);
692 struct pipe_surface
*ps_tex
= screen
->get_tex_surface(
693 screen
, pt
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE
);
694 if (pipe
->surface_copy
) {
695 pipe
->surface_copy(pipe
,
699 0, 0, src
->width
[0], src
->height
[0]);
701 util_surface_copy(pipe
, FALSE
,
705 0, 0, src
->width
[0], src
->height
[0]);
707 pipe_surface_reference(&ps_read
, NULL
);
708 pipe_surface_reference(&ps_tex
, NULL
);
715 void renderer_copy_pixmap(struct xorg_renderer
*r
,
716 struct exa_pixmap_priv
*dst_priv
, int dx
, int dy
,
717 struct exa_pixmap_priv
*src_priv
, int sx
, int sy
,
718 int width
, int height
)
720 float dst_loc
[4], src_loc
[4];
721 float dst_bounds
[4], src_bounds
[4];
722 float src_shift
[4], dst_shift
[4], shift
[4];
723 struct pipe_texture
*dst
= dst_priv
->tex
;
724 struct pipe_texture
*src
= src_priv
->tex
;
726 if (r
->pipe
->is_texture_referenced(r
->pipe
, src
, 0, 0) &
727 PIPE_REFERENCED_FOR_WRITE
)
728 r
->pipe
->flush(r
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
736 dst_bounds
[2] = dst
->width
[0];
737 dst_bounds
[3] = dst
->height
[0];
745 src_bounds
[2] = src
->width
[0];
746 src_bounds
[3] = src
->height
[0];
748 bound_rect(src_loc
, src_bounds
, src_shift
);
749 bound_rect(dst_loc
, dst_bounds
, dst_shift
);
750 shift
[0] = src_shift
[0] - dst_shift
[0];
751 shift
[1] = src_shift
[1] - dst_shift
[1];
754 shift_rectx(src_loc
, src_bounds
, -shift
[0]);
756 shift_rectx(dst_loc
, dst_bounds
, shift
[0]);
759 shift_recty(src_loc
, src_bounds
, -shift
[1]);
761 shift_recty(dst_loc
, dst_bounds
, shift
[1]);
763 sync_size(src_loc
, dst_loc
);
765 if (src_loc
[2] >= 0 && src_loc
[3] >= 0 &&
766 dst_loc
[2] >= 0 && dst_loc
[3] >= 0) {
767 struct pipe_texture
*temp_src
= src
;
770 temp_src
= create_sampler_texture(r
, src
);
772 renderer_copy_texture(r
,
776 src_loc
[0] + src_loc
[2],
777 src_loc
[1] + src_loc
[3],
781 dst_loc
[0] + dst_loc
[2],
782 dst_loc
[1] + dst_loc
[3]);
785 pipe_texture_reference(&temp_src
, NULL
);
789 void renderer_draw_solid_rect(struct xorg_renderer
*r
,
794 struct pipe_context
*pipe
= r
->pipe
;
795 struct pipe_buffer
*buf
= 0;
798 debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
799 x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
801 setup_vertex0(r
->vertices2
[0], x0
, y0
, color
);
803 setup_vertex0(r
->vertices2
[1], x1
, y0
, color
);
805 setup_vertex0(r
->vertices2
[2], x1
, y1
, color
);
807 setup_vertex0(r
->vertices2
[3], x0
, y1
, color
);
809 buf
= pipe_user_buffer_create(pipe
->screen
,
811 sizeof(r
->vertices2
));
815 util_draw_vertex_buffer(pipe
, buf
, 0,
816 PIPE_PRIM_TRIANGLE_FAN
,
818 2); /* attribs/vert */
820 pipe_buffer_reference(&buf
, NULL
);
824 void renderer_draw_textures(struct xorg_renderer
*r
,
826 int width
, int height
,
827 struct pipe_texture
**textures
,
829 float *src_matrix
, float *mask_matrix
)
831 struct pipe_context
*pipe
= r
->pipe
;
832 struct pipe_buffer
*buf
= 0;
836 debug_printf("src_matrix = \n");
837 debug_printf("%f, %f, %f\n", src_matrix
[0], src_matrix
[1], src_matrix
[2]);
838 debug_printf("%f, %f, %f\n", src_matrix
[3], src_matrix
[4], src_matrix
[5]);
839 debug_printf("%f, %f, %f\n", src_matrix
[6], src_matrix
[7], src_matrix
[8]);
842 debug_printf("mask_matrix = \n");
843 debug_printf("%f, %f, %f\n", mask_matrix
[0], mask_matrix
[1], mask_matrix
[2]);
844 debug_printf("%f, %f, %f\n", mask_matrix
[3], mask_matrix
[4], mask_matrix
[5]);
845 debug_printf("%f, %f, %f\n", mask_matrix
[6], mask_matrix
[7], mask_matrix
[8]);
849 switch(num_textures
) {
851 buf
= setup_vertex_data1(r
,
852 pos
[0], pos
[1], /* src */
853 pos
[4], pos
[5], /* dst */
855 textures
[0], src_matrix
);
858 buf
= setup_vertex_data2(r
,
859 pos
[0], pos
[1], /* src */
860 pos
[2], pos
[3], /* mask */
861 pos
[4], pos
[5], /* dst */
863 textures
[0], textures
[1],
864 src_matrix
, mask_matrix
);
867 buf
= setup_vertex_data_yuv(r
,
874 debug_assert(!"Unsupported number of textures");
879 int num_attribs
= 1; /*pos*/
880 num_attribs
+= num_textures
;
882 util_draw_vertex_buffer(pipe
, buf
, 0,
883 PIPE_PRIM_TRIANGLE_FAN
,
885 num_attribs
); /* attribs/vert */
887 pipe_buffer_reference(&buf
, NULL
);