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 xorg_shaders_destroy(r
->shaders
);
292 cso_release_all(r
->cso
);
293 cso_destroy_context(r
->cso
);
298 void renderer_bind_framebuffer(struct xorg_renderer
*r
,
299 struct exa_pixmap_priv
*priv
)
302 struct pipe_framebuffer_state state
;
303 struct pipe_surface
*surface
= xorg_gpu_surface(r
->pipe
->screen
, priv
);
304 memset(&state
, 0, sizeof(struct pipe_framebuffer_state
));
306 state
.width
= priv
->tex
->width
[0];
307 state
.height
= priv
->tex
->height
[0];
310 state
.cbufs
[0] = surface
;
311 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
314 /* currently we don't use depth/stencil */
317 cso_set_framebuffer(r
->cso
, &state
);
319 /* we do fire and forget for the framebuffer, this is the forget part */
320 pipe_surface_reference(&surface
, NULL
);
323 void renderer_bind_viewport(struct xorg_renderer
*r
,
324 struct exa_pixmap_priv
*dst
)
326 int width
= dst
->tex
->width
[0];
327 int height
= dst
->tex
->height
[0];
329 /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
331 set_viewport(r
, width
, height
, Y0_TOP
);
334 void renderer_bind_rasterizer(struct xorg_renderer
*r
)
336 struct pipe_rasterizer_state raster
;
338 /* XXX: move to renderer_init_state? */
339 memset(&raster
, 0, sizeof(struct pipe_rasterizer_state
));
340 raster
.gl_rasterization_rules
= 1;
341 cso_set_rasterizer(r
->cso
, &raster
);
344 void renderer_set_constants(struct xorg_renderer
*r
,
349 struct pipe_constant_buffer
*cbuf
=
350 (shader_type
== PIPE_SHADER_VERTEX
) ? &r
->vs_const_buffer
:
353 pipe_buffer_reference(&cbuf
->buffer
, NULL
);
354 cbuf
->buffer
= pipe_buffer_create(r
->pipe
->screen
, 16,
355 PIPE_BUFFER_USAGE_CONSTANT
,
359 pipe_buffer_write(r
->pipe
->screen
, cbuf
->buffer
,
360 0, param_bytes
, params
);
362 r
->pipe
->set_constant_buffer(r
->pipe
, shader_type
, 0, cbuf
);
366 setup_vs_constant_buffer(struct xorg_renderer
*r
,
367 int width
, int height
)
369 const int param_bytes
= 8 * sizeof(float);
370 float vs_consts
[8] = {
371 2.f
/width
, 2.f
/height
, 1, 1,
374 renderer_set_constants(r
, PIPE_SHADER_VERTEX
,
375 vs_consts
, param_bytes
);
379 setup_fs_constant_buffer(struct xorg_renderer
*r
)
381 const int param_bytes
= 4 * sizeof(float);
382 const float fs_consts
[8] = {
385 renderer_set_constants(r
, PIPE_SHADER_FRAGMENT
,
386 fs_consts
, param_bytes
);
389 static INLINE
void shift_rectx(float coords
[4],
396 coords
[2] = MIN2(coords
[2], bounds
[2]);
397 /* bound x/y + width/height */
398 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
399 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
404 static INLINE
void shift_recty(float coords
[4],
411 coords
[3] = MIN2(coords
[3], bounds
[3]);
412 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
413 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
418 static INLINE
void bound_rect(float coords
[4],
419 const float bounds
[4],
422 /* if outside the bounds */
423 if (coords
[0] > (bounds
[0] + bounds
[2]) ||
424 coords
[1] > (bounds
[1] + bounds
[3]) ||
425 (coords
[0] + coords
[2]) < bounds
[0] ||
426 (coords
[1] + coords
[3]) < bounds
[1]) {
437 if (coords
[0] < bounds
[0]) {
438 shift
[0] = bounds
[0] - coords
[0];
439 coords
[2] -= shift
[0];
440 coords
[0] = bounds
[0];
445 if (coords
[1] < bounds
[1]) {
446 shift
[1] = bounds
[1] - coords
[1];
447 coords
[3] -= shift
[1];
448 coords
[1] = bounds
[1];
452 shift
[2] = bounds
[2] - coords
[2];
453 shift
[3] = bounds
[3] - coords
[3];
454 /* bound width/height */
455 coords
[2] = MIN2(coords
[2], bounds
[2]);
456 coords
[3] = MIN2(coords
[3], bounds
[3]);
458 /* bound x/y + width/height */
459 if ((coords
[0] + coords
[2]) > (bounds
[0] + bounds
[2])) {
460 coords
[2] = (bounds
[0] + bounds
[2]) - coords
[0];
462 if ((coords
[1] + coords
[3]) > (bounds
[1] + bounds
[3])) {
463 coords
[3] = (bounds
[1] + bounds
[3]) - coords
[1];
466 /* if outside the bounds */
467 if ((coords
[0] + coords
[2]) < bounds
[0] ||
468 (coords
[1] + coords
[3]) < bounds
[1]) {
477 static INLINE
void sync_size(float *src_loc
, float *dst_loc
)
479 src_loc
[2] = MIN2(src_loc
[2], dst_loc
[2]);
480 src_loc
[3] = MIN2(src_loc
[3], dst_loc
[3]);
481 dst_loc
[2] = src_loc
[2];
482 dst_loc
[3] = src_loc
[3];
485 static void renderer_copy_texture(struct xorg_renderer
*r
,
486 struct pipe_texture
*src
,
487 float sx1
, float sy1
,
488 float sx2
, float sy2
,
489 struct pipe_texture
*dst
,
490 float dx1
, float dy1
,
491 float dx2
, float dy2
)
493 struct pipe_context
*pipe
= r
->pipe
;
494 struct pipe_screen
*screen
= pipe
->screen
;
495 struct pipe_buffer
*buf
;
496 struct pipe_surface
*dst_surf
= screen
->get_tex_surface(
497 screen
, dst
, 0, 0, 0,
498 PIPE_BUFFER_USAGE_GPU_WRITE
);
499 struct pipe_framebuffer_state fb
;
500 float s0
, t0
, s1
, t1
;
501 struct xorg_shader shader
;
503 assert(src
->width
[0] != 0);
504 assert(src
->height
[0] != 0);
505 assert(dst
->width
[0] != 0);
506 assert(dst
->height
[0] != 0);
509 s0
= sx1
/ src
->width
[0];
510 s1
= sx2
/ src
->width
[0];
511 t0
= sy1
/ src
->height
[0];
512 t1
= sy2
/ src
->height
[0];
521 debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
522 sx1
, sy1
, sx2
, sy2
, dx1
, dy1
, dx2
, dy2
,
526 assert(screen
->is_format_supported(screen
, dst_surf
->format
,
528 PIPE_TEXTURE_USAGE_RENDER_TARGET
,
531 /* save state (restored below) */
532 cso_save_blend(r
->cso
);
533 cso_save_samplers(r
->cso
);
534 cso_save_sampler_textures(r
->cso
);
535 cso_save_framebuffer(r
->cso
);
536 cso_save_fragment_shader(r
->cso
);
537 cso_save_vertex_shader(r
->cso
);
539 cso_save_viewport(r
->cso
);
542 /* set misc state we care about */
544 struct pipe_blend_state blend
;
545 memset(&blend
, 0, sizeof(blend
));
546 blend
.rgb_src_factor
= PIPE_BLENDFACTOR_ONE
;
547 blend
.alpha_src_factor
= PIPE_BLENDFACTOR_ONE
;
548 blend
.rgb_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
549 blend
.alpha_dst_factor
= PIPE_BLENDFACTOR_ZERO
;
550 blend
.colormask
= PIPE_MASK_RGBA
;
551 cso_set_blend(r
->cso
, &blend
);
556 struct pipe_sampler_state sampler
;
557 memset(&sampler
, 0, sizeof(sampler
));
558 sampler
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
559 sampler
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
560 sampler
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
561 sampler
.min_mip_filter
= PIPE_TEX_MIPFILTER_NONE
;
562 sampler
.min_img_filter
= PIPE_TEX_FILTER_NEAREST
;
563 sampler
.mag_img_filter
= PIPE_TEX_FILTER_NEAREST
;
564 sampler
.normalized_coords
= 1;
565 cso_single_sampler(r
->cso
, 0, &sampler
);
566 cso_single_sampler_done(r
->cso
);
569 set_viewport(r
, dst_surf
->width
, dst_surf
->height
, Y0_TOP
);
572 cso_set_sampler_textures(r
->cso
, 1, &src
);
574 renderer_bind_rasterizer(r
);
577 shader
= xorg_shaders_get(r
->shaders
,
580 cso_set_vertex_shader_handle(r
->cso
, shader
.vs
);
581 cso_set_fragment_shader_handle(r
->cso
, shader
.fs
);
584 memset(&fb
, 0, sizeof(fb
));
585 fb
.width
= dst_surf
->width
;
586 fb
.height
= dst_surf
->height
;
588 fb
.cbufs
[0] = dst_surf
;
591 for (i
= 1; i
< PIPE_MAX_COLOR_BUFS
; ++i
)
594 cso_set_framebuffer(r
->cso
, &fb
);
595 setup_vs_constant_buffer(r
, fb
.width
, fb
.height
);
596 setup_fs_constant_buffer(r
);
599 buf
= setup_vertex_data_tex(r
,
606 util_draw_vertex_buffer(r
->pipe
, buf
, 0,
607 PIPE_PRIM_TRIANGLE_FAN
,
609 2); /* attribs/vert */
611 pipe_buffer_reference(&buf
, NULL
);
614 /* restore state we changed */
615 cso_restore_blend(r
->cso
);
616 cso_restore_samplers(r
->cso
);
617 cso_restore_sampler_textures(r
->cso
);
618 cso_restore_framebuffer(r
->cso
);
619 cso_restore_vertex_shader(r
->cso
);
620 cso_restore_fragment_shader(r
->cso
);
621 cso_restore_viewport(r
->cso
);
623 pipe_surface_reference(&dst_surf
, NULL
);
626 static struct pipe_texture
*
627 create_sampler_texture(struct xorg_renderer
*r
,
628 struct pipe_texture
*src
)
630 enum pipe_format format
;
631 struct pipe_context
*pipe
= r
->pipe
;
632 struct pipe_screen
*screen
= pipe
->screen
;
633 struct pipe_texture
*pt
;
634 struct pipe_texture templ
;
636 pipe
->flush(pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
638 /* the coming in texture should already have that invariance */
639 debug_assert(screen
->is_format_supported(screen
, src
->format
,
641 PIPE_TEXTURE_USAGE_SAMPLER
, 0));
643 format
= src
->format
;
645 memset(&templ
, 0, sizeof(templ
));
646 templ
.target
= PIPE_TEXTURE_2D
;
647 templ
.format
= format
;
648 templ
.last_level
= 0;
649 templ
.width
[0] = src
->width
[0];
650 templ
.height
[0] = src
->height
[0];
652 pf_get_block(format
, &templ
.block
);
653 templ
.tex_usage
= PIPE_TEXTURE_USAGE_SAMPLER
;
655 pt
= screen
->texture_create(screen
, &templ
);
657 debug_assert(!pt
|| pipe_is_referenced(&pt
->reference
));
663 /* copy source framebuffer surface into texture */
664 struct pipe_surface
*ps_read
= screen
->get_tex_surface(
665 screen
, src
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ
);
666 struct pipe_surface
*ps_tex
= screen
->get_tex_surface(
667 screen
, pt
, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE
);
668 if (pipe
->surface_copy
) {
669 pipe
->surface_copy(pipe
,
673 0, 0, src
->width
[0], src
->height
[0]);
675 util_surface_copy(pipe
, FALSE
,
679 0, 0, src
->width
[0], src
->height
[0]);
681 pipe_surface_reference(&ps_read
, NULL
);
682 pipe_surface_reference(&ps_tex
, NULL
);
689 void renderer_copy_pixmap(struct xorg_renderer
*r
,
690 struct exa_pixmap_priv
*dst_priv
, int dx
, int dy
,
691 struct exa_pixmap_priv
*src_priv
, int sx
, int sy
,
692 int width
, int height
)
694 float dst_loc
[4], src_loc
[4];
695 float dst_bounds
[4], src_bounds
[4];
696 float src_shift
[4], dst_shift
[4], shift
[4];
697 struct pipe_texture
*dst
= dst_priv
->tex
;
698 struct pipe_texture
*src
= src_priv
->tex
;
700 if (r
->pipe
->is_texture_referenced(r
->pipe
, src
, 0, 0) &
701 PIPE_REFERENCED_FOR_WRITE
)
702 r
->pipe
->flush(r
->pipe
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
710 dst_bounds
[2] = dst
->width
[0];
711 dst_bounds
[3] = dst
->height
[0];
719 src_bounds
[2] = src
->width
[0];
720 src_bounds
[3] = src
->height
[0];
722 bound_rect(src_loc
, src_bounds
, src_shift
);
723 bound_rect(dst_loc
, dst_bounds
, dst_shift
);
724 shift
[0] = src_shift
[0] - dst_shift
[0];
725 shift
[1] = src_shift
[1] - dst_shift
[1];
728 shift_rectx(src_loc
, src_bounds
, -shift
[0]);
730 shift_rectx(dst_loc
, dst_bounds
, shift
[0]);
733 shift_recty(src_loc
, src_bounds
, -shift
[1]);
735 shift_recty(dst_loc
, dst_bounds
, shift
[1]);
737 sync_size(src_loc
, dst_loc
);
739 if (src_loc
[2] >= 0 && src_loc
[3] >= 0 &&
740 dst_loc
[2] >= 0 && dst_loc
[3] >= 0) {
741 struct pipe_texture
*temp_src
= src
;
744 temp_src
= create_sampler_texture(r
, src
);
746 renderer_copy_texture(r
,
750 src_loc
[0] + src_loc
[2],
751 src_loc
[1] + src_loc
[3],
755 dst_loc
[0] + dst_loc
[2],
756 dst_loc
[1] + dst_loc
[3]);
759 pipe_texture_reference(&temp_src
, NULL
);
763 void renderer_draw_solid_rect(struct xorg_renderer
*r
,
768 struct pipe_context
*pipe
= r
->pipe
;
769 struct pipe_buffer
*buf
= 0;
772 debug_printf("solid rect[(%d, %d), (%d, %d)], rgba[%f, %f, %f, %f]\n",
773 x0, y0, x1, y1, color[0], color[1], color[2], color[3]);*/
775 setup_vertex0(r
->vertices2
[0], x0
, y0
, color
);
777 setup_vertex0(r
->vertices2
[1], x1
, y0
, color
);
779 setup_vertex0(r
->vertices2
[2], x1
, y1
, color
);
781 setup_vertex0(r
->vertices2
[3], x0
, y1
, color
);
783 buf
= pipe_user_buffer_create(pipe
->screen
,
785 sizeof(r
->vertices2
));
789 util_draw_vertex_buffer(pipe
, buf
, 0,
790 PIPE_PRIM_TRIANGLE_FAN
,
792 2); /* attribs/vert */
794 pipe_buffer_reference(&buf
, NULL
);
798 void renderer_draw_textures(struct xorg_renderer
*r
,
800 int width
, int height
,
801 struct pipe_texture
**textures
,
803 float *src_matrix
, float *mask_matrix
)
805 struct pipe_context
*pipe
= r
->pipe
;
806 struct pipe_buffer
*buf
= 0;
808 switch(num_textures
) {
810 buf
= setup_vertex_data1(r
,
811 pos
[0], pos
[1], /* src */
812 pos
[4], pos
[5], /* dst */
814 textures
[0], src_matrix
);
817 buf
= setup_vertex_data2(r
,
818 pos
[0], pos
[1], /* src */
819 pos
[2], pos
[3], /* mask */
820 pos
[4], pos
[5], /* dst */
822 textures
[0], textures
[1],
823 src_matrix
, mask_matrix
);
826 debug_assert(!"Unsupported number of textures");
831 int num_attribs
= 1; /*pos*/
832 num_attribs
+= num_textures
;
834 util_draw_vertex_buffer(pipe
, buf
, 0,
835 PIPE_PRIM_TRIANGLE_FAN
,
837 num_attribs
); /* attribs/vert */
839 pipe_buffer_reference(&buf
, NULL
);