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 int srcX
, int srcY
, int dstX
, int dstY
,
90 int width
, int height
,
91 struct pipe_texture
*src
, float *src_matrix
)
93 float s0
, t0
, s1
, t1
, stmp
, ttmp
;
95 s0
= srcX
/ src
->width
[0];
96 s1
= srcX
+ width
/ src
->width
[0];
97 t0
= srcY
/ src
->height
[0];
98 t1
= srcY
+ height
/ src
->height
[0];
102 map_point(src_matrix
, s0
, t0
, &stmp
, &ttmp
);
103 setup_vertex1(r
->vertices2
[0], dstX
, dstY
, stmp
, ttmp
);
105 map_point(src_matrix
, s1
, t0
, &stmp
, &ttmp
);
106 setup_vertex1(r
->vertices2
[1], dstX
+ width
, dstY
, stmp
, ttmp
);
108 map_point(src_matrix
, s1
, t1
, &stmp
, &ttmp
);
109 setup_vertex1(r
->vertices2
[2], dstX
+ width
, dstY
+ height
, stmp
, ttmp
);
111 map_point(src_matrix
, s0
, t1
, &stmp
, &ttmp
);
112 setup_vertex1(r
->vertices2
[3], dstX
, dstY
+ height
, stmp
, ttmp
);
115 setup_vertex1(r
->vertices2
[0], dstX
, dstY
, s0
, t0
);
117 setup_vertex1(r
->vertices2
[1], dstX
+ width
, dstY
, s1
, t0
);
119 setup_vertex1(r
->vertices2
[2], dstX
+ width
, dstY
+ height
, s1
, t1
);
121 setup_vertex1(r
->vertices2
[3], dstX
, dstY
+ height
, s0
, t1
);
124 return pipe_user_buffer_create(r
->pipe
->screen
,
126 sizeof(r
->vertices2
));
129 static struct pipe_buffer
*
130 setup_vertex_data_tex(struct xorg_renderer
*r
,
131 float x0
, float y0
, float x1
, float y1
,
132 float s0
, float t0
, float s1
, float t1
,
136 setup_vertex1(r
->vertices2
[0], x0
, y0
, s0
, t0
);
138 setup_vertex1(r
->vertices2
[1], x1
, y0
, s1
, t0
);
140 setup_vertex1(r
->vertices2
[2], x1
, y1
, s1
, t1
);
142 setup_vertex1(r
->vertices2
[3], x0
, y1
, s0
, t1
);
144 return pipe_user_buffer_create(r
->pipe
->screen
,
146 sizeof(r
->vertices2
));
150 setup_vertex2(float vertex
[3][4], float x
, float y
,
151 float s0
, float t0
, float s1
, float t1
)
155 vertex
[0][2] = 0.f
; /*z*/
156 vertex
[0][3] = 1.f
; /*w*/
158 vertex
[1][0] = s0
; /*s*/
159 vertex
[1][1] = t0
; /*t*/
160 vertex
[1][2] = 0.f
; /*r*/
161 vertex
[1][3] = 1.f
; /*q*/
163 vertex
[2][0] = s1
; /*s*/
164 vertex
[2][1] = t1
; /*t*/
165 vertex
[2][2] = 0.f
; /*r*/
166 vertex
[2][3] = 1.f
; /*q*/
169 static struct pipe_buffer
*
170 setup_vertex_data2(struct xorg_renderer
*r
,
171 int srcX
, int srcY
, int maskX
, int maskY
,
172 int dstX
, int dstY
, int width
, int height
,
173 struct pipe_texture
*src
,
174 struct pipe_texture
*mask
,
175 float *src_matrix
, float *mask_matrix
)
177 float st0
[4], st1
[4];
178 float pt0
[2], pt1
[2];
180 st0
[0] = srcX
/ src
->width
[0];
181 st0
[1] = srcY
/ src
->height
[0];
182 st0
[2] = srcX
+ width
/ src
->width
[0];
183 st0
[3] = srcY
+ height
/ src
->height
[0];
185 st1
[0] = maskX
/ mask
->width
[0];
186 st1
[1] = maskY
/ mask
->height
[0];
187 st1
[2] = maskX
+ width
/ mask
->width
[0];
188 st1
[3] = maskY
+ height
/ mask
->height
[0];
190 if (src_matrix
|| mask_matrix
) {
192 map_point(src_matrix
, st0
[0], st0
[1],
194 map_point(mask_matrix
, st1
[0], st1
[1],
196 setup_vertex2(r
->vertices3
[0], dstX
, dstY
,
197 pt0
[0], pt0
[1], pt1
[0], pt1
[1]);
199 map_point(src_matrix
, st0
[2], st0
[1],
201 map_point(mask_matrix
, st1
[2], st1
[1],
203 setup_vertex2(r
->vertices3
[1], dstX
+ width
, dstY
,
204 pt0
[0], pt0
[1], pt1
[0], pt1
[1]);
206 map_point(src_matrix
, st0
[2], st0
[3],
208 map_point(mask_matrix
, st1
[2], st1
[3],
210 setup_vertex2(r
->vertices3
[2], dstX
+ width
, dstY
+ height
,
211 pt0
[0], pt0
[1], pt1
[0], pt1
[1]);
213 map_point(src_matrix
, st0
[0], st0
[3],
215 map_point(mask_matrix
, st1
[0], st1
[3],
217 setup_vertex2(r
->vertices3
[3], dstX
, dstY
+ height
,
218 pt0
[0], pt0
[1], pt1
[0], pt1
[1]);
221 setup_vertex2(r
->vertices3
[0], dstX
, dstY
,
222 st0
[0], st0
[1], st1
[0], st1
[1]);
224 setup_vertex2(r
->vertices3
[1], dstX
+ width
, dstY
,
225 st0
[2], st0
[1], st1
[2], st1
[1]);
227 setup_vertex2(r
->vertices3
[2], dstX
+ width
, dstY
+ height
,
228 st0
[2], st0
[3], st1
[2], st1
[3]);
230 setup_vertex2(r
->vertices3
[3], dstX
, dstY
+ height
,
231 st0
[0], st0
[3], st1
[0], st1
[3]);
234 return pipe_user_buffer_create(r
->pipe
->screen
,
236 sizeof(r
->vertices3
));
242 set_viewport(struct xorg_renderer
*r
, int width
, int height
,
243 enum AxisOrientation orientation
)
245 struct pipe_viewport_state viewport
;
246 float y_scale
= (orientation
== Y0_BOTTOM
) ? -2.f
: 2.f
;
248 viewport
.scale
[0] = width
/ 2.f
;
249 viewport
.scale
[1] = height
/ y_scale
;
250 viewport
.scale
[2] = 1.0;
251 viewport
.scale
[3] = 1.0;
252 viewport
.translate
[0] = width
/ 2.f
;
253 viewport
.translate
[1] = height
/ 2.f
;
254 viewport
.translate
[2] = 0.0;
255 viewport
.translate
[3] = 0.0;
257 cso_set_viewport(r
->cso
, &viewport
);
262 struct xorg_renderer
* renderer_create(struct pipe_context
*pipe
)
264 struct xorg_renderer
*renderer
= CALLOC_STRUCT(xorg_renderer
);
266 renderer
->pipe
= pipe
;
267 renderer
->cso
= cso_create_context(pipe
);
268 renderer
->shaders
= xorg_shaders_create(renderer
);
270 renderer_init_state(renderer
);
275 void renderer_destroy(struct xorg_renderer
*r
)
277 struct pipe_constant_buffer
*vsbuf
= &r
->vs_const_buffer
;
278 struct pipe_constant_buffer
*fsbuf
= &r
->fs_const_buffer
;
280 if (vsbuf
&& vsbuf
->buffer
)
281 pipe_buffer_reference(&vsbuf
->buffer
, NULL
);
283 if (fsbuf
&& fsbuf
->buffer
)
284 pipe_buffer_reference(&fsbuf
->buffer
, NULL
);
287 cso_release_all(r
->cso
);
288 cso_destroy_context(r
->cso
);
292 xorg_shaders_destroy(r
->shaders
);
296 void renderer_bind_framebuffer(struct xorg_renderer
*r
,
297 struct exa_pixmap_priv
*priv
)
300 struct pipe_framebuffer_state state
;
301 struct pipe_surface
*surface
= xorg_gpu_surface(r
->pipe
->screen
, priv
);
302 memset(&state
, 0, sizeof(struct pipe_framebuffer_state
));
304 state
.width
= priv
->tex
->width
[0];
305 state
.height
= priv
->tex
->height
[0];
308 state
.cbufs
[0] = surface
;
309 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
312 /* currently we don't use depth/stencil */
315 cso_set_framebuffer(r
->cso
, &state
);
317 /* we do fire and forget for the framebuffer, this is the forget part */
318 pipe_surface_reference(&surface
, NULL
);
321 void renderer_bind_viewport(struct xorg_renderer
*r
,
322 struct exa_pixmap_priv
*dst
)
324 int width
= dst
->tex
->width
[0];
325 int height
= dst
->tex
->height
[0];
327 /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
329 set_viewport(r
, width
, height
, Y0_TOP
);
332 void renderer_bind_rasterizer(struct xorg_renderer
*r
)
334 struct pipe_rasterizer_state raster
;
336 /* XXX: move to renderer_init_state? */
337 memset(&raster
, 0, sizeof(struct pipe_rasterizer_state
));
338 raster
.gl_rasterization_rules
= 1;
339 cso_set_rasterizer(r
->cso
, &raster
);
342 void renderer_set_constants(struct xorg_renderer
*r
,
347 struct pipe_constant_buffer
*cbuf
=
348 (shader_type
== PIPE_SHADER_VERTEX
) ? &r
->vs_const_buffer
:
351 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
352 cbuf
->buffer
= pipe_buffer_create(r
->pipe
->screen
, 16,
353 PIPE_BUFFER_USAGE_CONSTANT
,
357 pipe_buffer_write(r
->pipe
->screen
, cbuf
->buffer
,
358 0, param_bytes
, params
);
360 r
->pipe
->set_constant_buffer(r
->pipe
, shader_type
, 0, cbuf
);
364 setup_vs_constant_buffer(struct xorg_renderer
*r
,
365 int width
, int height
)
367 const int param_bytes
= 8 * sizeof(float);
368 float vs_consts
[8] = {
369 2.f
/width
, 2.f
/height
, 1, 1,
372 renderer_set_constants(r
, PIPE_SHADER_VERTEX
,
373 vs_consts
, param_bytes
);
377 setup_fs_constant_buffer(struct xorg_renderer
*r
)
379 const int param_bytes
= 4 * sizeof(float);
380 const float fs_consts
[8] = {
383 renderer_set_constants(r
, PIPE_SHADER_FRAGMENT
,
384 fs_consts
, param_bytes
);
387 static INLINE
void shift_rectx(float coords
[4],
394 coords
[2] = MIN2(coords
[2], bounds
[2]);
395 /* bound x/y + width/height */
396 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
397 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
402 static INLINE
void shift_recty(float coords
[4],
409 coords
[3] = MIN2(coords
[3], bounds
[3]);
410 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
411 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
416 static INLINE
void bound_rect(float coords
[4],
417 const float bounds
[4],
420 /* if outside the bounds */
421 if (coords
[0] > (bounds
[0] + bounds
[2]) ||
422 coords
[1] > (bounds
[1] + bounds
[3]) ||
423 (coords
[0] + coords
[2]) < bounds
[0] ||
424 (coords
[1] + coords
[3]) < bounds
[1]) {
435 if (coords
[0] < bounds
[0]) {
436 shift
[0] = bounds
[0] - coords
[0];
437 coords
[2] -= shift
[0];
438 coords
[0] = bounds
[0];
443 if (coords
[1] < bounds
[1]) {
444 shift
[1] = bounds
[1] - coords
[1];
445 coords
[3] -= shift
[1];
446 coords
[1] = bounds
[1];
450 shift
[2] = bounds
[2] - coords
[2];
451 shift
[3] = bounds
[3] - coords
[3];
452 /* bound width/height */
453 coords
[2] = MIN2(coords
[2], bounds
[2]);
454 coords
[3] = MIN2(coords
[3], bounds
[3]);
456 /* bound x/y + width/height */
457 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
458 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
460 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
461 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
464 /* if outside the bounds */
465 if ((coords
[0] + coords
[2]) < bounds
[0] ||
466 (coords
[1] + coords
[3]) < bounds
[1]) {
475 static INLINE
void sync_size(float *src_loc
, float *dst_loc
)
477 src_loc
[2] = MIN2(src_loc
[2], dst_loc
[2]);
478 src_loc
[3] = MIN2(src_loc
[3], dst_loc
[3]);
479 dst_loc
[2] = src_loc
[2];
480 dst_loc
[3] = src_loc
[3];
483 static void renderer_copy_texture(struct xorg_renderer
*r
,
484 struct pipe_texture
*src
,
485 float sx1
, float sy1
,
486 float sx2
, float sy2
,
487 struct pipe_texture
*dst
,
488 float dx1
, float dy1
,
489 float dx2
, float dy2
)
491 struct pipe_context
*pipe
= r
->pipe
;
492 struct pipe_screen
*screen
= pipe
->screen
;
493 struct pipe_buffer
*buf
;
494 struct pipe_surface
*dst_surf
= screen
->get_tex_surface(
495 screen
, dst
, 0, 0, 0,
496 PIPE_BUFFER_USAGE_GPU_WRITE
);
497 struct pipe_framebuffer_state fb
;
498 float s0
, t0
, s1
, t1
;
499 struct xorg_shader shader
;
501 assert(src
->width
[0] != 0);
502 assert(src
->height
[0] != 0);
503 assert(dst
->width
[0] != 0);
504 assert(dst
->height
[0] != 0);
507 s0
= sx1
/ src
->width
[0];
508 s1
= sx2
/ src
->width
[0];
509 t0
= sy1
/ src
->height
[0];
510 t1
= sy2
/ src
->height
[0];
519 debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
520 sx1
, sy1
, sx2
, sy2
, dx1
, dy1
, dx2
, dy2
,
524 assert(screen
->is_format_supported(screen
, dst_surf
->format
,
526 PIPE_TEXTURE_USAGE_RENDER_TARGET
,
529 /* save state (restored below) */
530 cso_save_blend(r
->cso
);
531 cso_save_samplers(r
->cso
);
532 cso_save_sampler_textures(r
->cso
);
533 cso_save_framebuffer(r
->cso
);
534 cso_save_fragment_shader(r
->cso
);
535 cso_save_vertex_shader(r
->cso
);
537 cso_save_viewport(r
->cso
);
540 /* set misc state we care about */
542 struct pipe_blend_state blend
;
543 memset(&blend
, 0, sizeof(blend
));
544 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
545 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
546 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
547 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
548 blend
.colormask
= PIPE_MASK_RGBA
;
549 cso_set_blend(r
->cso
, &blend
);
554 struct pipe_sampler_state sampler
;
555 memset(&sampler
, 0, sizeof(sampler
));
556 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
557 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
558 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
559 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
560 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
561 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
562 sampler
.normalized_coords
= 1;
563 cso_single_sampler(r
->cso
, 0, &sampler
);
564 cso_single_sampler_done(r
->cso
);
567 set_viewport(r
, dst_surf
->width
, dst_surf
->height
, Y0_TOP
);
570 cso_set_sampler_textures(r
->cso
, 1, &src
);
572 renderer_bind_rasterizer(r
);
575 shader
= xorg_shaders_get(r
->shaders
,
578 cso_set_vertex_shader_handle(r
->cso
, shader
.vs
);
579 cso_set_fragment_shader_handle(r
->cso
, shader
.fs
);
582 memset(&fb
, 0, sizeof(fb
));
583 fb
.width
= dst_surf
->width
;
584 fb
.height
= dst_surf
->height
;
586 fb
.cbufs
[0] = dst_surf
;
589 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
592 cso_set_framebuffer(r
->cso
, &fb
);
593 setup_vs_constant_buffer(r
, fb
.width
, fb
.height
);
594 setup_fs_constant_buffer(r
);
597 buf
= setup_vertex_data_tex(r
,
604 util_draw_vertex_buffer(r
->pipe
, buf
, 0,
605 PIPE_PRIM_TRIANGLE_FAN
,
607 2); /* attribs/vert */
609 pipe_buffer_reference(&buf
, NULL
);
612 /* restore state we changed */
613 cso_restore_blend(r
->cso
);
614 cso_restore_samplers(r
->cso
);
615 cso_restore_sampler_textures(r
->cso
);
616 cso_restore_framebuffer(r
->cso
);
617 cso_restore_vertex_shader(r
->cso
);
618 cso_restore_fragment_shader(r
->cso
);
619 cso_restore_viewport(r
->cso
);
621 pipe_surface_reference(&dst_surf
, NULL
);
624 static struct pipe_texture
*
625 create_sampler_texture(struct xorg_renderer
*r
,
626 struct pipe_texture
*src
)
628 enum pipe_format format
;
629 struct pipe_context
*pipe
= r
->pipe
;
630 struct pipe_screen
*screen
= pipe
->screen
;
631 struct pipe_texture
*pt
;
632 struct pipe_texture templ
;
634 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
636 /* the coming in texture should already have that invariance */
637 debug_assert(screen
->is_format_supported(screen
, src
->format
,
639 PIPE_TEXTURE_USAGE_SAMPLER
, 0));
641 format
= src
->format
;
643 memset(&templ
, 0, sizeof(templ
));
644 templ
.target
= PIPE_TEXTURE_2D
;
645 templ
.format
= format
;
646 templ
.last_level
= 0;
647 templ
.width
[0] = src
->width
[0];
648 templ
.height
[0] = src
->height
[0];
650 pf_get_block(format
, &templ
.block
);
651 templ
.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
653 pt
= screen
->texture_create(screen
, &templ
);
655 debug_assert(!pt
|| pipe_is_referenced(&pt
->reference
));
661 /* copy source framebuffer surface into texture */
662 struct pipe_surface
*ps_read
= screen
->get_tex_surface(
663 screen
, src
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
);
664 struct pipe_surface
*ps_tex
= screen
->get_tex_surface(
665 screen
, pt
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE
);
666 if (pipe
->surface_copy
) {
667 pipe
->surface_copy(pipe
,
671 0, 0, src
->width
[0], src
->height
[0]);
673 util_surface_copy(pipe
, FALSE
,
677 0, 0, src
->width
[0], src
->height
[0]);
679 pipe_surface_reference(&ps_read
, NULL
);
680 pipe_surface_reference(&ps_tex
, NULL
);
687 void renderer_copy_pixmap(struct xorg_renderer
*r
,
688 struct exa_pixmap_priv
*dst_priv
, int dx
, int dy
,
689 struct exa_pixmap_priv
*src_priv
, int sx
, int sy
,
690 int width
, int height
)
692 float dst_loc
[4], src_loc
[4];
693 float dst_bounds
[4], src_bounds
[4];
694 float src_shift
[4], dst_shift
[4], shift
[4];
695 struct pipe_texture
*dst
= dst_priv
->tex
;
696 struct pipe_texture
*src
= src_priv
->tex
;
698 if (r
->pipe
->is_texture_referenced(r
->pipe
, src
, 0, 0) &
699 PIPE_REFERENCED_FOR_WRITE
)
700 r
->pipe
->flush(r
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
708 dst_bounds
[2] = dst
->width
[0];
709 dst_bounds
[3] = dst
->height
[0];
717 src_bounds
[2] = src
->width
[0];
718 src_bounds
[3] = src
->height
[0];
720 bound_rect(src_loc
, src_bounds
, src_shift
);
721 bound_rect(dst_loc
, dst_bounds
, dst_shift
);
722 shift
[0] = src_shift
[0] - dst_shift
[0];
723 shift
[1] = src_shift
[1] - dst_shift
[1];
726 shift_rectx(src_loc
, src_bounds
, -shift
[0]);
728 shift_rectx(dst_loc
, dst_bounds
, shift
[0]);
731 shift_recty(src_loc
, src_bounds
, -shift
[1]);
733 shift_recty(dst_loc
, dst_bounds
, shift
[1]);
735 sync_size(src_loc
, dst_loc
);
737 if (src_loc
[2] >= 0 && src_loc
[3] >= 0 &&
738 dst_loc
[2] >= 0 && dst_loc
[3] >= 0) {
739 struct pipe_texture
*temp_src
= src
;
742 temp_src
= create_sampler_texture(r
, src
);
744 renderer_copy_texture(r
,
748 src_loc
[0] + src_loc
[2],
749 src_loc
[1] + src_loc
[3],
753 dst_loc
[0] + dst_loc
[2],
754 dst_loc
[1] + dst_loc
[3]);
757 pipe_texture_reference(&temp_src
, NULL
);
761 void renderer_draw_solid_rect(struct xorg_renderer
*r
,
766 struct pipe_context
*pipe
= r
->pipe
;
767 struct pipe_buffer
*buf
= 0;
770 debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
771 x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
773 setup_vertex0(r
->vertices2
[0], x0
, y0
, color
);
775 setup_vertex0(r
->vertices2
[1], x1
, y0
, color
);
777 setup_vertex0(r
->vertices2
[2], x1
, y1
, color
);
779 setup_vertex0(r
->vertices2
[3], x0
, y1
, color
);
781 buf
= pipe_user_buffer_create(pipe
->screen
,
783 sizeof(r
->vertices2
));
787 util_draw_vertex_buffer(pipe
, buf
, 0,
788 PIPE_PRIM_TRIANGLE_FAN
,
790 2); /* attribs/vert */
792 pipe_buffer_reference(&buf
, NULL
);
796 void renderer_draw_textures(struct xorg_renderer
*r
,
798 int width
, int height
,
799 struct pipe_texture
**textures
,
801 float *src_matrix
, float *mask_matrix
)
803 struct pipe_context
*pipe
= r
->pipe
;
804 struct pipe_buffer
*buf
= 0;
806 switch(num_textures
) {
808 buf
= setup_vertex_data1(r
,
809 pos
[0], pos
[1], /* src */
810 pos
[4], pos
[5], /* dst */
812 textures
[0], src_matrix
);
815 buf
= setup_vertex_data2(r
,
816 pos
[0], pos
[1], /* src */
817 pos
[2], pos
[3], /* mask */
818 pos
[4], pos
[5], /* dst */
820 textures
[0], textures
[1],
821 src_matrix
, mask_matrix
);
824 debug_assert(!"Unsupported number of textures");
829 int num_attribs
= 1; /*pos*/
830 num_attribs
+= num_textures
;
832 util_draw_vertex_buffer(pipe
, buf
, 0,
833 PIPE_PRIM_TRIANGLE_FAN
,
835 num_attribs
); /* attribs/vert */
837 pipe_buffer_reference(&buf
, NULL
);