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 /* Templates for various state objects. */
60 struct pipe_depth_stencil_alpha_state template_dsa
;
61 struct pipe_sampler_state template_sampler_state
;
63 /* Constant state objects. */
65 void *vs_col
; /**< Vertex shader which passes {pos, color} to the output */
66 void *vs_tex
; /**<Vertex shader which passes {pos, texcoord} to the output.*/
68 /* Fragment shaders. */
69 /* FS which outputs a color to multiple color buffers. */
70 void *fs_col
[PIPE_MAX_COLOR_BUFS
];
72 /* FS which outputs a color from a texture,
73 where the index is PIPE_TEXTURE_* to be sampled. */
74 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
76 /* FS which outputs a depth from a texture,
77 where the index is PIPE_TEXTURE_* to be sampled. */
78 void *fs_texfetch_depth
[PIPE_MAX_TEXTURE_TYPES
];
81 void *blend_write_color
; /**< blend state with writemask of RGBA */
82 void *blend_keep_color
; /**< blend state with writemask of 0 */
84 /* Depth stencil alpha state. */
85 void *dsa_write_depth_stencil
[0xff]; /**< indices are stencil clear values */
86 void *dsa_write_depth_keep_stencil
;
87 void *dsa_keep_depth_stencil
;
89 /* Sampler state for clamping to a miplevel. */
90 void *sampler_state
[PIPE_MAX_TEXTURE_LEVELS
];
92 /* Rasterizer state. */
96 struct blitter_context
*util_blitter_create(struct pipe_context
*pipe
)
98 struct blitter_context_priv
*ctx
;
99 struct pipe_blend_state blend
;
100 struct pipe_depth_stencil_alpha_state
*dsa
;
101 struct pipe_rasterizer_state rs_state
;
102 struct pipe_sampler_state
*sampler_state
;
105 ctx
= CALLOC_STRUCT(blitter_context_priv
);
111 /* init state objects for them to be considered invalid */
112 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
113 ctx
->blitter
.saved_num_textures
= ~0;
114 ctx
->blitter
.saved_num_sampler_states
= ~0;
116 /* blend state objects */
117 memset(&blend
, 0, sizeof(blend
));
118 ctx
->blend_keep_color
= pipe
->create_blend_state(pipe
, &blend
);
120 blend
.colormask
= PIPE_MASK_RGBA
;
121 ctx
->blend_write_color
= pipe
->create_blend_state(pipe
, &blend
);
123 /* depth stencil alpha state objects */
124 dsa
= &ctx
->template_dsa
;
125 ctx
->dsa_keep_depth_stencil
=
126 pipe
->create_depth_stencil_alpha_state(pipe
, dsa
);
128 dsa
->depth
.enabled
= 1;
129 dsa
->depth
.writemask
= 1;
130 dsa
->depth
.func
= PIPE_FUNC_ALWAYS
;
131 ctx
->dsa_write_depth_keep_stencil
=
132 pipe
->create_depth_stencil_alpha_state(pipe
, dsa
);
134 dsa
->stencil
[0].enabled
= 1;
135 dsa
->stencil
[0].func
= PIPE_FUNC_ALWAYS
;
136 dsa
->stencil
[0].fail_op
= PIPE_STENCIL_OP_REPLACE
;
137 dsa
->stencil
[0].zpass_op
= PIPE_STENCIL_OP_REPLACE
;
138 dsa
->stencil
[0].zfail_op
= PIPE_STENCIL_OP_REPLACE
;
139 dsa
->stencil
[0].valuemask
= 0xff;
140 dsa
->stencil
[0].writemask
= 0xff;
141 /* The DSA state objects which write depth and stencil are created
145 sampler_state
= &ctx
->template_sampler_state
;
146 sampler_state
->wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
147 sampler_state
->wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
148 sampler_state
->wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
149 /* The sampler state objects which sample from a specified mipmap level
150 * are created on-demand. */
152 /* rasterizer state */
153 memset(&rs_state
, 0, sizeof(rs_state
));
154 rs_state
.front_winding
= PIPE_WINDING_CW
;
155 rs_state
.cull_mode
= PIPE_WINDING_NONE
;
156 rs_state
.bypass_vs_clip_and_viewport
= 1;
157 rs_state
.gl_rasterization_rules
= 1;
158 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
160 /* fragment shaders are created on-demand */
164 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
165 TGSI_SEMANTIC_COLOR
};
166 const uint semantic_indices
[] = { 0, 0 };
168 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
172 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
173 TGSI_SEMANTIC_GENERIC
};
174 const uint semantic_indices
[] = { 0, 0 };
176 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
180 /* set invariant vertex coordinates */
181 for (i
= 0; i
< 4; i
++)
182 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
184 /* create the vertex buffer */
185 ctx
->vbuf
= pipe_buffer_create(ctx
->pipe
->screen
,
187 PIPE_BUFFER_USAGE_VERTEX
,
188 sizeof(ctx
->vertices
));
190 return &ctx
->blitter
;
193 void util_blitter_destroy(struct blitter_context
*blitter
)
195 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
196 struct pipe_context
*pipe
= ctx
->pipe
;
199 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
200 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
201 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
202 pipe
->delete_depth_stencil_alpha_state(pipe
,
203 ctx
->dsa_write_depth_keep_stencil
);
205 for (i
= 0; i
< 0xff; i
++)
206 if (ctx
->dsa_write_depth_stencil
[i
])
207 pipe
->delete_depth_stencil_alpha_state(pipe
,
208 ctx
->dsa_write_depth_stencil
[i
]);
210 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
211 pipe
->delete_vs_state(pipe
, ctx
->vs_col
);
212 pipe
->delete_vs_state(pipe
, ctx
->vs_tex
);
214 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
215 if (ctx
->fs_texfetch_col
[i
])
216 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
217 if (ctx
->fs_texfetch_depth
[i
])
218 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
221 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
&& ctx
->fs_col
[i
]; i
++)
223 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
225 for (i
= 0; i
< PIPE_MAX_TEXTURE_LEVELS
; i
++)
226 if (ctx
->sampler_state
[i
])
227 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
[i
]);
229 pipe_buffer_reference(&ctx
->vbuf
, NULL
);
233 static void blitter_check_saved_CSOs(struct blitter_context_priv
*ctx
)
235 /* make sure these CSOs have been saved */
236 assert(ctx
->blitter
.saved_blend_state
&&
237 ctx
->blitter
.saved_dsa_state
&&
238 ctx
->blitter
.saved_rs_state
&&
239 ctx
->blitter
.saved_fs
&&
240 ctx
->blitter
.saved_vs
);
243 static void blitter_restore_CSOs(struct blitter_context_priv
*ctx
)
245 struct pipe_context
*pipe
= ctx
->pipe
;
247 /* restore the state objects which are always required to be saved */
248 pipe
->bind_blend_state(pipe
, ctx
->blitter
.saved_blend_state
);
249 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->blitter
.saved_dsa_state
);
250 pipe
->bind_rasterizer_state(pipe
, ctx
->blitter
.saved_rs_state
);
251 pipe
->bind_fs_state(pipe
, ctx
->blitter
.saved_fs
);
252 pipe
->bind_vs_state(pipe
, ctx
->blitter
.saved_vs
);
254 ctx
->blitter
.saved_blend_state
= 0;
255 ctx
->blitter
.saved_dsa_state
= 0;
256 ctx
->blitter
.saved_rs_state
= 0;
257 ctx
->blitter
.saved_fs
= 0;
258 ctx
->blitter
.saved_vs
= 0;
260 /* restore the state objects which are required to be saved before copy/fill
262 if (ctx
->blitter
.saved_fb_state
.nr_cbufs
!= ~0) {
263 pipe
->set_framebuffer_state(pipe
, &ctx
->blitter
.saved_fb_state
);
264 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
267 if (ctx
->blitter
.saved_num_sampler_states
!= ~0) {
268 pipe
->bind_fragment_sampler_states(pipe
,
269 ctx
->blitter
.saved_num_sampler_states
,
270 ctx
->blitter
.saved_sampler_states
);
271 ctx
->blitter
.saved_num_sampler_states
= ~0;
274 if (ctx
->blitter
.saved_num_textures
!= ~0) {
275 pipe
->set_fragment_sampler_textures(pipe
,
276 ctx
->blitter
.saved_num_textures
,
277 ctx
->blitter
.saved_textures
);
278 ctx
->blitter
.saved_num_textures
= ~0;
282 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
283 unsigned x1
, unsigned y1
,
284 unsigned x2
, unsigned y2
,
289 /* set vertex positions */
290 ctx
->vertices
[0][0][0] = x1
; /*v0.x*/
291 ctx
->vertices
[0][0][1] = y1
; /*v0.y*/
293 ctx
->vertices
[1][0][0] = x2
; /*v1.x*/
294 ctx
->vertices
[1][0][1] = y1
; /*v1.y*/
296 ctx
->vertices
[2][0][0] = x2
; /*v2.x*/
297 ctx
->vertices
[2][0][1] = y2
; /*v2.y*/
299 ctx
->vertices
[3][0][0] = x1
; /*v3.x*/
300 ctx
->vertices
[3][0][1] = y2
; /*v3.y*/
302 for (i
= 0; i
< 4; i
++)
303 ctx
->vertices
[i
][0][2] = depth
; /*z*/
306 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
311 for (i
= 0; i
< 4; i
++) {
312 ctx
->vertices
[i
][1][0] = rgba
[0];
313 ctx
->vertices
[i
][1][1] = rgba
[1];
314 ctx
->vertices
[i
][1][2] = rgba
[2];
315 ctx
->vertices
[i
][1][3] = rgba
[3];
319 static void blitter_set_texcoords_2d(struct blitter_context_priv
*ctx
,
320 struct pipe_surface
*surf
,
321 unsigned x1
, unsigned y1
,
322 unsigned x2
, unsigned y2
)
325 float s1
= x1
/ (float)surf
->width
;
326 float t1
= y1
/ (float)surf
->height
;
327 float s2
= x2
/ (float)surf
->width
;
328 float t2
= y2
/ (float)surf
->height
;
330 ctx
->vertices
[0][1][0] = s1
; /*t0.s*/
331 ctx
->vertices
[0][1][1] = t1
; /*t0.t*/
333 ctx
->vertices
[1][1][0] = s2
; /*t1.s*/
334 ctx
->vertices
[1][1][1] = t1
; /*t1.t*/
336 ctx
->vertices
[2][1][0] = s2
; /*t2.s*/
337 ctx
->vertices
[2][1][1] = t2
; /*t2.t*/
339 ctx
->vertices
[3][1][0] = s1
; /*t3.s*/
340 ctx
->vertices
[3][1][1] = t2
; /*t3.t*/
342 for (i
= 0; i
< 4; i
++) {
343 ctx
->vertices
[i
][1][2] = 0; /*r*/
344 ctx
->vertices
[i
][1][3] = 1; /*q*/
348 static void blitter_set_texcoords_3d(struct blitter_context_priv
*ctx
,
349 struct pipe_surface
*surf
,
350 unsigned x1
, unsigned y1
,
351 unsigned x2
, unsigned y2
)
354 float depth
= u_minify(surf
->texture
->depth0
, surf
->level
);
355 float r
= surf
->zslice
/ depth
;
357 blitter_set_texcoords_2d(ctx
, surf
, x1
, y1
, x2
, y2
);
359 for (i
= 0; i
< 4; i
++)
360 ctx
->vertices
[i
][1][2] = r
; /*r*/
363 static void blitter_set_texcoords_cube(struct blitter_context_priv
*ctx
,
364 struct pipe_surface
*surf
,
365 unsigned x1
, unsigned y1
,
366 unsigned x2
, unsigned y2
)
369 float s1
= x1
/ (float)surf
->width
;
370 float t1
= y1
/ (float)surf
->height
;
371 float s2
= x2
/ (float)surf
->width
;
372 float t2
= y2
/ (float)surf
->height
;
373 const float st
[4][2] = {
374 {s1
, t1
}, {s2
, t1
}, {s2
, t2
}, {s1
, t2
}
377 util_map_texcoords2d_onto_cubemap(surf
->face
,
378 /* pointer, stride in floats */
380 &ctx
->vertices
[0][1][0], 8);
382 for (i
= 0; i
< 4; i
++)
383 ctx
->vertices
[i
][1][3] = 1; /*q*/
386 static void blitter_draw_quad(struct blitter_context_priv
*ctx
)
388 struct blitter_context
*blitter
= &ctx
->blitter
;
389 struct pipe_context
*pipe
= ctx
->pipe
;
391 if (blitter
->draw_quad
) {
392 blitter
->draw_quad(pipe
, &ctx
->vertices
[0][0][0]);
394 /* write vertices and draw them */
395 pipe_buffer_write(pipe
->screen
, ctx
->vbuf
,
396 0, sizeof(ctx
->vertices
), ctx
->vertices
);
398 util_draw_vertex_buffer(ctx
->pipe
, ctx
->vbuf
, 0, PIPE_PRIM_TRIANGLE_FAN
,
400 2); /* attribs/vert */
405 void *blitter_get_state_write_depth_stencil(
406 struct blitter_context_priv
*ctx
,
409 struct pipe_context
*pipe
= ctx
->pipe
;
413 /* Create the DSA state on-demand. */
414 if (!ctx
->dsa_write_depth_stencil
[stencil
]) {
415 ctx
->template_dsa
.stencil
[0].ref_value
= stencil
;
417 ctx
->dsa_write_depth_stencil
[stencil
] =
418 pipe
->create_depth_stencil_alpha_state(pipe
, &ctx
->template_dsa
);
421 return ctx
->dsa_write_depth_stencil
[stencil
];
425 void **blitter_get_sampler_state(struct blitter_context_priv
*ctx
,
428 struct pipe_context
*pipe
= ctx
->pipe
;
429 struct pipe_sampler_state
*sampler_state
= &ctx
->template_sampler_state
;
431 assert(miplevel
< PIPE_MAX_TEXTURE_LEVELS
);
433 /* Create the sampler state on-demand. */
434 if (!ctx
->sampler_state
[miplevel
]) {
435 sampler_state
->lod_bias
= miplevel
;
436 sampler_state
->min_lod
= miplevel
;
437 sampler_state
->max_lod
= miplevel
;
439 ctx
->sampler_state
[miplevel
] = pipe
->create_sampler_state(pipe
,
443 /* Return void** so that it can be passed to bind_fragment_sampler_states
445 return &ctx
->sampler_state
[miplevel
];
449 void *blitter_get_fs_col(struct blitter_context_priv
*ctx
, unsigned num_cbufs
)
451 struct pipe_context
*pipe
= ctx
->pipe
;
452 unsigned index
= num_cbufs
? num_cbufs
- 1 : 0;
454 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
456 if (!ctx
->fs_col
[index
])
458 util_make_fragment_clonecolor_shader(pipe
, num_cbufs
);
460 return ctx
->fs_col
[index
];
464 void *blitter_get_fs_texfetch_col(struct blitter_context_priv
*ctx
,
467 struct pipe_context
*pipe
= ctx
->pipe
;
469 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
471 /* Create the fragment shader on-demand. */
472 if (!ctx
->fs_texfetch_col
[tex_target
]) {
473 switch (tex_target
) {
474 case PIPE_TEXTURE_1D
:
475 ctx
->fs_texfetch_col
[PIPE_TEXTURE_1D
] =
476 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_1D
);
478 case PIPE_TEXTURE_2D
:
479 ctx
->fs_texfetch_col
[PIPE_TEXTURE_2D
] =
480 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_2D
);
482 case PIPE_TEXTURE_3D
:
483 ctx
->fs_texfetch_col
[PIPE_TEXTURE_3D
] =
484 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_3D
);
486 case PIPE_TEXTURE_CUBE
:
487 ctx
->fs_texfetch_col
[PIPE_TEXTURE_CUBE
] =
488 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_CUBE
);
494 return ctx
->fs_texfetch_col
[tex_target
];
498 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv
*ctx
,
501 struct pipe_context
*pipe
= ctx
->pipe
;
503 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
505 /* Create the fragment shader on-demand. */
506 if (!ctx
->fs_texfetch_depth
[tex_target
]) {
507 switch (tex_target
) {
508 case PIPE_TEXTURE_1D
:
509 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_1D
] =
510 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_1D
);
512 case PIPE_TEXTURE_2D
:
513 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_2D
] =
514 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_2D
);
516 case PIPE_TEXTURE_3D
:
517 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_3D
] =
518 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_3D
);
520 case PIPE_TEXTURE_CUBE
:
521 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_CUBE
] =
522 util_make_fragment_tex_shader_writedepth(pipe
,TGSI_TEXTURE_CUBE
);
528 return ctx
->fs_texfetch_depth
[tex_target
];
531 void util_blitter_clear(struct blitter_context
*blitter
,
532 unsigned width
, unsigned height
,
534 unsigned clear_buffers
,
536 double depth
, unsigned stencil
)
538 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
539 struct pipe_context
*pipe
= ctx
->pipe
;
541 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
543 blitter_check_saved_CSOs(ctx
);
546 if (clear_buffers
& PIPE_CLEAR_COLOR
)
547 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
549 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
551 if (clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
)
552 pipe
->bind_depth_stencil_alpha_state(pipe
,
553 blitter_get_state_write_depth_stencil(ctx
, stencil
));
555 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
557 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
558 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, num_cbufs
));
559 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
561 blitter_set_clear_color(ctx
, rgba
);
562 blitter_set_rectangle(ctx
, 0, 0, width
, height
, depth
);
563 blitter_draw_quad(ctx
);
564 blitter_restore_CSOs(ctx
);
567 void util_blitter_copy(struct blitter_context
*blitter
,
568 struct pipe_surface
*dst
,
569 unsigned dstx
, unsigned dsty
,
570 struct pipe_surface
*src
,
571 unsigned srcx
, unsigned srcy
,
572 unsigned width
, unsigned height
,
573 boolean ignore_stencil
)
575 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
576 struct pipe_context
*pipe
= ctx
->pipe
;
577 struct pipe_screen
*screen
= pipe
->screen
;
578 struct pipe_framebuffer_state fb_state
;
579 boolean is_stencil
, is_depth
;
580 unsigned dst_tex_usage
;
582 /* give up if textures are not set */
583 assert(dst
->texture
&& src
->texture
);
584 if (!dst
->texture
|| !src
->texture
)
587 is_depth
= pf_get_component_bits(src
->format
, PIPE_FORMAT_COMP_Z
) != 0;
588 is_stencil
= pf_get_component_bits(src
->format
, PIPE_FORMAT_COMP_S
) != 0;
589 dst_tex_usage
= is_depth
|| is_stencil
? PIPE_TEXTURE_USAGE_DEPTH_STENCIL
:
590 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
592 /* check if we can sample from and render to the surfaces */
593 /* (assuming copying a stencil buffer is not possible) */
594 if ((!ignore_stencil
&& is_stencil
) ||
595 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
597 !screen
->is_format_supported(screen
, src
->format
, src
->texture
->target
,
598 PIPE_TEXTURE_USAGE_SAMPLER
, 0)) {
599 util_surface_copy(pipe
, FALSE
, dst
, dstx
, dsty
, src
, srcx
, srcy
,
604 /* check whether the states are properly saved */
605 blitter_check_saved_CSOs(ctx
);
606 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
607 assert(blitter
->saved_num_textures
!= ~0);
608 assert(blitter
->saved_num_sampler_states
!= ~0);
609 assert(src
->texture
->target
< PIPE_MAX_TEXTURE_TYPES
);
612 fb_state
.width
= dst
->width
;
613 fb_state
.height
= dst
->height
;
616 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
617 pipe
->bind_depth_stencil_alpha_state(pipe
,
618 ctx
->dsa_write_depth_keep_stencil
);
619 pipe
->bind_fs_state(pipe
,
620 blitter_get_fs_texfetch_depth(ctx
, src
->texture
->target
));
622 fb_state
.nr_cbufs
= 0;
623 fb_state
.zsbuf
= dst
;
625 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
626 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
627 pipe
->bind_fs_state(pipe
,
628 blitter_get_fs_texfetch_col(ctx
, src
->texture
->target
));
630 fb_state
.nr_cbufs
= 1;
631 fb_state
.cbufs
[0] = dst
;
635 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
636 pipe
->bind_vs_state(pipe
, ctx
->vs_tex
);
637 pipe
->bind_fragment_sampler_states(pipe
, 1,
638 blitter_get_sampler_state(ctx
, src
->level
));
639 pipe
->set_fragment_sampler_textures(pipe
, 1, &src
->texture
);
640 pipe
->set_framebuffer_state(pipe
, &fb_state
);
642 /* set texture coordinates */
643 switch (src
->texture
->target
) {
644 case PIPE_TEXTURE_1D
:
645 case PIPE_TEXTURE_2D
:
646 blitter_set_texcoords_2d(ctx
, src
, srcx
, srcy
,
647 srcx
+width
, srcy
+height
);
649 case PIPE_TEXTURE_3D
:
650 blitter_set_texcoords_3d(ctx
, src
, srcx
, srcy
,
651 srcx
+width
, srcy
+height
);
653 case PIPE_TEXTURE_CUBE
:
654 blitter_set_texcoords_cube(ctx
, src
, srcx
, srcy
,
655 srcx
+width
, srcy
+height
);
661 blitter_set_rectangle(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0);
662 blitter_draw_quad(ctx
);
663 blitter_restore_CSOs(ctx
);
666 void util_blitter_fill(struct blitter_context
*blitter
,
667 struct pipe_surface
*dst
,
668 unsigned dstx
, unsigned dsty
,
669 unsigned width
, unsigned height
,
672 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
673 struct pipe_context
*pipe
= ctx
->pipe
;
674 struct pipe_screen
*screen
= pipe
->screen
;
675 struct pipe_framebuffer_state fb_state
;
677 ubyte ub_rgba
[4] = {0};
678 union util_color color
;
681 assert(dst
->texture
);
685 /* check if we can render to the surface */
686 if (pf_is_depth_or_stencil(dst
->format
) || /* unlikely, but you never know */
687 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
688 PIPE_TEXTURE_USAGE_RENDER_TARGET
, 0)) {
689 util_surface_fill(pipe
, dst
, dstx
, dsty
, width
, height
, value
);
693 /* unpack the color */
695 util_unpack_color_ub(dst
->format
, &color
,
696 ub_rgba
, ub_rgba
+1, ub_rgba
+2, ub_rgba
+3);
697 for (i
= 0; i
< 4; i
++)
698 rgba
[i
] = ubyte_to_float(ub_rgba
[i
]);
700 /* check the saved state */
701 blitter_check_saved_CSOs(ctx
);
702 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
705 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
706 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
707 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
708 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 1));
709 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
711 /* set a framebuffer state */
712 fb_state
.width
= dst
->width
;
713 fb_state
.height
= dst
->height
;
714 fb_state
.nr_cbufs
= 1;
715 fb_state
.cbufs
[0] = dst
;
717 pipe
->set_framebuffer_state(pipe
, &fb_state
);
719 blitter_set_clear_color(ctx
, rgba
);
720 blitter_set_rectangle(ctx
, 0, 0, width
, height
, 0);
721 blitter_draw_quad(ctx
);
722 blitter_restore_CSOs(ctx
);