1 /**************************************************************************
3 * Copyright 2009 Marek Olšák <maraeo@gmail.com>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
29 * Blitter utility to facilitate acceleration of the clear, surface_copy,
30 * and surface_fill functions.
35 #include "pipe/p_context.h"
36 #include "pipe/p_defines.h"
37 #include "pipe/p_inlines.h"
38 #include "pipe/p_shader_tokens.h"
39 #include "pipe/p_state.h"
41 #include "util/u_memory.h"
42 #include "util/u_math.h"
43 #include "util/u_blitter.h"
44 #include "util/u_draw_quad.h"
45 #include "util/u_pack_color.h"
46 #include "util/u_rect.h"
47 #include "util/u_simple_shaders.h"
48 #include "util/u_texture.h"
50 struct blitter_context_priv
52 struct blitter_context blitter
;
54 struct pipe_context
*pipe
; /**< pipe context */
55 struct pipe_buffer
*vbuf
; /**< quad */
57 float vertices
[4][2][4]; /**< {pos, color} or {pos, texcoord} */
59 /* Constant state objects. */
61 void *vs_col
; /**< Vertex shader which passes {pos, color} to the output */
62 void *vs_tex
; /**<Vertex shader which passes {pos, texcoord} to the output.*/
64 /* Fragment shaders. */
65 /* FS which outputs a color to multiple color buffers. */
66 void *fs_col
[PIPE_MAX_COLOR_BUFS
];
68 /* FS which outputs a color from a texture,
69 where the index is PIPE_TEXTURE_* to be sampled. */
70 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
72 /* FS which outputs a depth from a texture,
73 where the index is PIPE_TEXTURE_* to be sampled. */
74 void *fs_texfetch_depth
[PIPE_MAX_TEXTURE_TYPES
];
77 void *blend_write_color
; /**< blend state with writemask of RGBA */
78 void *blend_keep_color
; /**< blend state with writemask of 0 */
80 /* Depth stencil alpha state. */
81 void *dsa_write_depth_stencil
[0xff]; /**< indices are stencil clear values */
82 void *dsa_write_depth_keep_stencil
;
83 void *dsa_keep_depth_stencil
;
85 /* Sampler state for clamping to a miplevel. */
86 void *sampler_state
[PIPE_MAX_TEXTURE_LEVELS
];
88 /* Rasterizer state. */
92 struct blitter_context
*util_blitter_create(struct pipe_context
*pipe
)
94 struct blitter_context_priv
*ctx
;
95 struct pipe_blend_state blend
;
96 struct pipe_depth_stencil_alpha_state dsa
;
97 struct pipe_rasterizer_state rs_state
;
98 struct pipe_sampler_state sampler_state
;
99 unsigned i
, max_render_targets
;
101 ctx
= CALLOC_STRUCT(blitter_context_priv
);
107 /* init state objects for them to be considered invalid */
108 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
109 ctx
->blitter
.saved_num_textures
= ~0;
110 ctx
->blitter
.saved_num_sampler_states
= ~0;
112 /* blend state objects */
113 memset(&blend
, 0, sizeof(blend
));
114 ctx
->blend_keep_color
= pipe
->create_blend_state(pipe
, &blend
);
116 blend
.colormask
= PIPE_MASK_RGBA
;
117 ctx
->blend_write_color
= pipe
->create_blend_state(pipe
, &blend
);
119 /* depth stencil alpha state objects */
120 memset(&dsa
, 0, sizeof(dsa
));
121 ctx
->dsa_keep_depth_stencil
=
122 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
124 dsa
.depth
.enabled
= 1;
125 dsa
.depth
.writemask
= 1;
126 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
127 ctx
->dsa_write_depth_keep_stencil
=
128 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
130 dsa
.stencil
[0].enabled
= 1;
131 dsa
.stencil
[0].func
= PIPE_FUNC_ALWAYS
;
132 dsa
.stencil
[0].fail_op
= PIPE_STENCIL_OP_REPLACE
;
133 dsa
.stencil
[0].zpass_op
= PIPE_STENCIL_OP_REPLACE
;
134 dsa
.stencil
[0].zfail_op
= PIPE_STENCIL_OP_REPLACE
;
135 dsa
.stencil
[0].valuemask
= 0xff;
136 dsa
.stencil
[0].writemask
= 0xff;
138 /* create a depth stencil alpha state for each possible stencil clear
140 for (i
= 0; i
< 0xff; i
++) {
141 dsa
.stencil
[0].ref_value
= i
;
143 ctx
->dsa_write_depth_stencil
[i
] =
144 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
148 memset(&sampler_state
, 0, sizeof(sampler_state
));
149 sampler_state
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
150 sampler_state
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
151 sampler_state
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
153 for (i
= 0; i
< PIPE_MAX_TEXTURE_LEVELS
; i
++) {
154 sampler_state
.lod_bias
= i
;
155 sampler_state
.min_lod
= i
;
156 sampler_state
.max_lod
= i
;
158 ctx
->sampler_state
[i
] = pipe
->create_sampler_state(pipe
, &sampler_state
);
161 /* rasterizer state */
162 memset(&rs_state
, 0, sizeof(rs_state
));
163 rs_state
.front_winding
= PIPE_WINDING_CW
;
164 rs_state
.cull_mode
= PIPE_WINDING_NONE
;
165 rs_state
.bypass_vs_clip_and_viewport
= 1;
166 rs_state
.gl_rasterization_rules
= 1;
167 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
171 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
172 TGSI_SEMANTIC_COLOR
};
173 const uint semantic_indices
[] = { 0, 0 };
175 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
179 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
180 TGSI_SEMANTIC_GENERIC
};
181 const uint semantic_indices
[] = { 0, 0 };
183 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
187 /* fragment shaders */
188 ctx
->fs_texfetch_col
[PIPE_TEXTURE_1D
] =
189 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_1D
);
190 ctx
->fs_texfetch_col
[PIPE_TEXTURE_2D
] =
191 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_2D
);
192 ctx
->fs_texfetch_col
[PIPE_TEXTURE_3D
] =
193 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_3D
);
194 ctx
->fs_texfetch_col
[PIPE_TEXTURE_CUBE
] =
195 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_CUBE
);
197 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_1D
] =
198 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_1D
);
199 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_2D
] =
200 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_2D
);
201 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_3D
] =
202 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_3D
);
203 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_CUBE
] =
204 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_CUBE
);
206 max_render_targets
= pipe
->screen
->get_param(pipe
->screen
,
207 PIPE_CAP_MAX_RENDER_TARGETS
);
208 assert(max_render_targets
<= PIPE_MAX_COLOR_BUFS
);
209 for (i
= 0; i
< max_render_targets
; i
++)
210 ctx
->fs_col
[i
] = util_make_fragment_clonecolor_shader(pipe
, 1+i
);
212 /* set invariant vertex coordinates */
213 for (i
= 0; i
< 4; i
++)
214 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
216 /* create the vertex buffer */
217 ctx
->vbuf
= pipe_buffer_create(ctx
->pipe
->screen
,
219 PIPE_BUFFER_USAGE_VERTEX
,
220 sizeof(ctx
->vertices
));
222 return &ctx
->blitter
;
225 void util_blitter_destroy(struct blitter_context
*blitter
)
227 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
228 struct pipe_context
*pipe
= ctx
->pipe
;
231 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
232 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
233 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
234 pipe
->delete_depth_stencil_alpha_state(pipe
,
235 ctx
->dsa_write_depth_keep_stencil
);
237 for (i
= 0; i
< 0xff; i
++)
238 pipe
->delete_depth_stencil_alpha_state(pipe
,
239 ctx
->dsa_write_depth_stencil
[i
]);
241 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
242 pipe
->delete_vs_state(pipe
, ctx
->vs_col
);
243 pipe
->delete_vs_state(pipe
, ctx
->vs_tex
);
245 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
246 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
247 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
250 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
&& ctx
->fs_col
[i
]; i
++)
251 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
253 for (i
= 0; i
< PIPE_MAX_TEXTURE_LEVELS
; i
++)
254 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
[i
]);
256 pipe_buffer_reference(&ctx
->vbuf
, NULL
);
260 static void blitter_check_saved_CSOs(struct blitter_context_priv
*ctx
)
262 /* make sure these CSOs have been saved */
263 assert(ctx
->blitter
.saved_blend_state
&&
264 ctx
->blitter
.saved_dsa_state
&&
265 ctx
->blitter
.saved_rs_state
&&
266 ctx
->blitter
.saved_fs
&&
267 ctx
->blitter
.saved_vs
);
270 static void blitter_restore_CSOs(struct blitter_context_priv
*ctx
)
272 struct pipe_context
*pipe
= ctx
->pipe
;
274 /* restore the state objects which are always required to be saved */
275 pipe
->bind_blend_state(pipe
, ctx
->blitter
.saved_blend_state
);
276 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->blitter
.saved_dsa_state
);
277 pipe
->bind_rasterizer_state(pipe
, ctx
->blitter
.saved_rs_state
);
278 pipe
->bind_fs_state(pipe
, ctx
->blitter
.saved_fs
);
279 pipe
->bind_vs_state(pipe
, ctx
->blitter
.saved_vs
);
281 ctx
->blitter
.saved_blend_state
= 0;
282 ctx
->blitter
.saved_dsa_state
= 0;
283 ctx
->blitter
.saved_rs_state
= 0;
284 ctx
->blitter
.saved_fs
= 0;
285 ctx
->blitter
.saved_vs
= 0;
287 /* restore the state objects which are required to be saved before copy/fill
289 if (ctx
->blitter
.saved_fb_state
.nr_cbufs
!= ~0) {
290 pipe
->set_framebuffer_state(pipe
, &ctx
->blitter
.saved_fb_state
);
291 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
294 if (ctx
->blitter
.saved_num_sampler_states
!= ~0) {
295 pipe
->bind_fragment_sampler_states(pipe
,
296 ctx
->blitter
.saved_num_sampler_states
,
297 ctx
->blitter
.saved_sampler_states
);
298 ctx
->blitter
.saved_num_sampler_states
= ~0;
301 if (ctx
->blitter
.saved_num_textures
!= ~0) {
302 pipe
->set_fragment_sampler_textures(pipe
,
303 ctx
->blitter
.saved_num_textures
,
304 ctx
->blitter
.saved_textures
);
305 ctx
->blitter
.saved_num_textures
= ~0;
309 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
310 unsigned x1
, unsigned y1
,
311 unsigned x2
, unsigned y2
,
316 /* set vertex positions */
317 ctx
->vertices
[0][0][0] = x1
; /*v0.x*/
318 ctx
->vertices
[0][0][1] = y1
; /*v0.y*/
320 ctx
->vertices
[1][0][0] = x2
; /*v1.x*/
321 ctx
->vertices
[1][0][1] = y1
; /*v1.y*/
323 ctx
->vertices
[2][0][0] = x2
; /*v2.x*/
324 ctx
->vertices
[2][0][1] = y2
; /*v2.y*/
326 ctx
->vertices
[3][0][0] = x1
; /*v3.x*/
327 ctx
->vertices
[3][0][1] = y2
; /*v3.y*/
329 for (i
= 0; i
< 4; i
++)
330 ctx
->vertices
[i
][0][2] = depth
; /*z*/
333 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
338 for (i
= 0; i
< 4; i
++) {
339 ctx
->vertices
[i
][1][0] = rgba
[0];
340 ctx
->vertices
[i
][1][1] = rgba
[1];
341 ctx
->vertices
[i
][1][2] = rgba
[2];
342 ctx
->vertices
[i
][1][3] = rgba
[3];
346 static void blitter_set_texcoords_2d(struct blitter_context_priv
*ctx
,
347 struct pipe_surface
*surf
,
348 unsigned x1
, unsigned y1
,
349 unsigned x2
, unsigned y2
)
352 float s1
= x1
/ (float)surf
->width
;
353 float t1
= y1
/ (float)surf
->height
;
354 float s2
= x2
/ (float)surf
->width
;
355 float t2
= y2
/ (float)surf
->height
;
357 ctx
->vertices
[0][1][0] = s1
; /*t0.s*/
358 ctx
->vertices
[0][1][1] = t1
; /*t0.t*/
360 ctx
->vertices
[1][1][0] = s2
; /*t1.s*/
361 ctx
->vertices
[1][1][1] = t1
; /*t1.t*/
363 ctx
->vertices
[2][1][0] = s2
; /*t2.s*/
364 ctx
->vertices
[2][1][1] = t2
; /*t2.t*/
366 ctx
->vertices
[3][1][0] = s1
; /*t3.s*/
367 ctx
->vertices
[3][1][1] = t2
; /*t3.t*/
369 for (i
= 0; i
< 4; i
++) {
370 ctx
->vertices
[i
][1][2] = 0; /*r*/
371 ctx
->vertices
[i
][1][3] = 1; /*q*/
375 static void blitter_set_texcoords_3d(struct blitter_context_priv
*ctx
,
376 struct pipe_surface
*surf
,
377 unsigned x1
, unsigned y1
,
378 unsigned x2
, unsigned y2
)
381 float depth
= u_minify(surf
->texture
->depth0
, surf
->level
);
382 float r
= surf
->zslice
/ depth
;
384 blitter_set_texcoords_2d(ctx
, surf
, x1
, y1
, x2
, y2
);
386 for (i
= 0; i
< 4; i
++)
387 ctx
->vertices
[i
][1][2] = r
; /*r*/
390 static void blitter_set_texcoords_cube(struct blitter_context_priv
*ctx
,
391 struct pipe_surface
*surf
,
392 unsigned x1
, unsigned y1
,
393 unsigned x2
, unsigned y2
)
396 float s1
= x1
/ (float)surf
->width
;
397 float t1
= y1
/ (float)surf
->height
;
398 float s2
= x2
/ (float)surf
->width
;
399 float t2
= y2
/ (float)surf
->height
;
400 const float st
[4][2] = {
401 {s1
, t1
}, {s2
, t1
}, {s2
, t2
}, {s1
, t2
}
404 util_map_texcoords2d_onto_cubemap(surf
->face
,
405 /* pointer, stride in floats */
407 &ctx
->vertices
[0][1][0], 8);
409 for (i
= 0; i
< 4; i
++)
410 ctx
->vertices
[i
][1][3] = 1; /*q*/
413 static void blitter_draw_quad(struct blitter_context_priv
*ctx
)
415 struct blitter_context
*blitter
= &ctx
->blitter
;
416 struct pipe_context
*pipe
= ctx
->pipe
;
418 if (blitter
->draw_quad
) {
419 blitter
->draw_quad(pipe
, &ctx
->vertices
[0][0][0]);
421 /* write vertices and draw them */
422 pipe_buffer_write(pipe
->screen
, ctx
->vbuf
,
423 0, sizeof(ctx
->vertices
), ctx
->vertices
);
425 util_draw_vertex_buffer(ctx
->pipe
, ctx
->vbuf
, 0, PIPE_PRIM_TRIANGLE_FAN
,
427 2); /* attribs/vert */
431 void util_blitter_clear(struct blitter_context
*blitter
,
432 unsigned width
, unsigned height
,
434 unsigned clear_buffers
,
436 double depth
, unsigned stencil
)
438 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
439 struct pipe_context
*pipe
= ctx
->pipe
;
441 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
443 blitter_check_saved_CSOs(ctx
);
446 if (clear_buffers
& PIPE_CLEAR_COLOR
)
447 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
449 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
451 if (clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
)
452 pipe
->bind_depth_stencil_alpha_state(pipe
,
453 ctx
->dsa_write_depth_stencil
[stencil
&0xff]);
455 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
457 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
458 pipe
->bind_fs_state(pipe
, ctx
->fs_col
[num_cbufs
? num_cbufs
-1 : 0]);
459 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
461 blitter_set_clear_color(ctx
, rgba
);
462 blitter_set_rectangle(ctx
, 0, 0, width
, height
, depth
);
463 blitter_draw_quad(ctx
);
464 blitter_restore_CSOs(ctx
);
467 void util_blitter_copy(struct blitter_context
*blitter
,
468 struct pipe_surface
*dst
,
469 unsigned dstx
, unsigned dsty
,
470 struct pipe_surface
*src
,
471 unsigned srcx
, unsigned srcy
,
472 unsigned width
, unsigned height
,
473 boolean ignore_stencil
)
475 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
476 struct pipe_context
*pipe
= ctx
->pipe
;
477 struct pipe_screen
*screen
= pipe
->screen
;
478 struct pipe_framebuffer_state fb_state
;
479 boolean is_stencil
, is_depth
;
480 unsigned dst_tex_usage
;
482 /* give up if textures are not set */
483 assert(dst
->texture
&& src
->texture
);
484 if (!dst
->texture
|| !src
->texture
)
487 is_depth
= pf_get_component_bits(src
->format
, PIPE_FORMAT_COMP_Z
) != 0;
488 is_stencil
= pf_get_component_bits(src
->format
, PIPE_FORMAT_COMP_S
) != 0;
489 dst_tex_usage
= is_depth
|| is_stencil
? PIPE_TEXTURE_USAGE_DEPTH_STENCIL
:
490 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
492 /* check if we can sample from and render to the surfaces */
493 /* (assuming copying a stencil buffer is not possible) */
494 if ((!ignore_stencil
&& is_stencil
) ||
495 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
497 !screen
->is_format_supported(screen
, src
->format
, src
->texture
->target
,
498 PIPE_TEXTURE_USAGE_SAMPLER
, 0)) {
499 util_surface_copy(pipe
, FALSE
, dst
, dstx
, dsty
, src
, srcx
, srcy
,
504 /* check whether the states are properly saved */
505 blitter_check_saved_CSOs(ctx
);
506 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
507 assert(blitter
->saved_num_textures
!= ~0);
508 assert(blitter
->saved_num_sampler_states
!= ~0);
509 assert(src
->texture
->target
< PIPE_MAX_TEXTURE_TYPES
);
512 fb_state
.width
= dst
->width
;
513 fb_state
.height
= dst
->height
;
516 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
517 pipe
->bind_depth_stencil_alpha_state(pipe
,
518 ctx
->dsa_write_depth_keep_stencil
);
519 pipe
->bind_fs_state(pipe
, ctx
->fs_texfetch_depth
[src
->texture
->target
]);
521 fb_state
.nr_cbufs
= 0;
522 fb_state
.zsbuf
= dst
;
524 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
525 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
526 pipe
->bind_fs_state(pipe
, ctx
->fs_texfetch_col
[src
->texture
->target
]);
528 fb_state
.nr_cbufs
= 1;
529 fb_state
.cbufs
[0] = dst
;
532 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
533 pipe
->bind_vs_state(pipe
, ctx
->vs_tex
);
534 pipe
->bind_fragment_sampler_states(pipe
, 1, &ctx
->sampler_state
[src
->level
]);
535 pipe
->set_fragment_sampler_textures(pipe
, 1, &src
->texture
);
536 pipe
->set_framebuffer_state(pipe
, &fb_state
);
538 /* set texture coordinates */
539 switch (src
->texture
->target
) {
540 case PIPE_TEXTURE_1D
:
541 case PIPE_TEXTURE_2D
:
542 blitter_set_texcoords_2d(ctx
, src
, srcx
, srcy
,
543 srcx
+width
, srcy
+height
);
545 case PIPE_TEXTURE_3D
:
546 blitter_set_texcoords_3d(ctx
, src
, srcx
, srcy
,
547 srcx
+width
, srcy
+height
);
549 case PIPE_TEXTURE_CUBE
:
550 blitter_set_texcoords_cube(ctx
, src
, srcx
, srcy
,
551 srcx
+width
, srcy
+height
);
557 blitter_set_rectangle(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0);
558 blitter_draw_quad(ctx
);
559 blitter_restore_CSOs(ctx
);
562 void util_blitter_fill(struct blitter_context
*blitter
,
563 struct pipe_surface
*dst
,
564 unsigned dstx
, unsigned dsty
,
565 unsigned width
, unsigned height
,
568 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
569 struct pipe_context
*pipe
= ctx
->pipe
;
570 struct pipe_screen
*screen
= pipe
->screen
;
571 struct pipe_framebuffer_state fb_state
;
573 ubyte ub_rgba
[4] = {0};
574 union util_color color
;
577 assert(dst
->texture
);
581 /* check if we can render to the surface */
582 if (pf_is_depth_or_stencil(dst
->format
) || /* unlikely, but you never know */
583 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
584 PIPE_TEXTURE_USAGE_RENDER_TARGET
, 0)) {
585 util_surface_fill(pipe
, dst
, dstx
, dsty
, width
, height
, value
);
589 /* unpack the color */
591 util_unpack_color_ub(dst
->format
, &color
,
592 ub_rgba
, ub_rgba
+1, ub_rgba
+2, ub_rgba
+3);
593 for (i
= 0; i
< 4; i
++)
594 rgba
[i
] = ubyte_to_float(ub_rgba
[i
]);
596 /* check the saved state */
597 blitter_check_saved_CSOs(ctx
);
598 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
601 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
602 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
603 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
604 pipe
->bind_fs_state(pipe
, ctx
->fs_col
[0]);
605 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
607 /* set a framebuffer state */
608 fb_state
.width
= dst
->width
;
609 fb_state
.height
= dst
->height
;
610 fb_state
.nr_cbufs
= 1;
611 fb_state
.cbufs
[0] = dst
;
613 pipe
->set_framebuffer_state(pipe
, &fb_state
);
615 blitter_set_clear_color(ctx
, rgba
);
616 blitter_set_rectangle(ctx
, 0, 0, width
, height
, 0);
617 blitter_draw_quad(ctx
);
618 blitter_restore_CSOs(ctx
);