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, clear_render_target,
30 * clear_depth_stencil, and resource_copy_region functions.
35 #include "pipe/p_context.h"
36 #include "pipe/p_defines.h"
37 #include "util/u_inlines.h"
38 #include "pipe/p_shader_tokens.h"
39 #include "pipe/p_state.h"
41 #include "util/u_format.h"
42 #include "util/u_memory.h"
43 #include "util/u_math.h"
44 #include "util/u_blitter.h"
45 #include "util/u_draw_quad.h"
46 #include "util/u_sampler.h"
47 #include "util/u_simple_shaders.h"
48 #include "util/u_surface.h"
49 #include "util/u_texture.h"
51 #define INVALID_PTR ((void*)~0)
53 struct blitter_context_priv
55 struct blitter_context base
;
57 struct pipe_resource
*vbuf
; /**< quad */
59 float vertices
[4][2][4]; /**< {pos, color} or {pos, texcoord} */
61 /* Templates for various state objects. */
63 /* Constant state objects. */
65 void *vs
; /**< Vertex shader which passes {pos, generic} to the output.*/
66 void *vs_pos_only
; /**< Vertex shader which passes pos to the output.*/
68 /* Fragment shaders. */
69 /* The shader at index i outputs color to color buffers 0,1,...,i-1. */
70 void *fs_col
[PIPE_MAX_COLOR_BUFS
+1];
71 void *fs_col_int
[PIPE_MAX_COLOR_BUFS
+1];
73 /* FS which outputs a color from a texture,
74 where the index is PIPE_TEXTURE_* to be sampled. */
75 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
77 /* FS which outputs a depth from a texture,
78 where the index is PIPE_TEXTURE_* to be sampled. */
79 void *fs_texfetch_depth
[PIPE_MAX_TEXTURE_TYPES
];
82 void *blend_write_color
; /**< blend state with writemask of RGBA */
83 void *blend_keep_color
; /**< blend state with writemask of 0 */
85 /* Depth stencil alpha state. */
86 void *dsa_write_depth_stencil
;
87 void *dsa_write_depth_keep_stencil
;
88 void *dsa_keep_depth_stencil
;
89 void *dsa_keep_depth_write_stencil
;
91 /* Vertex elements states. */
93 void *velem_uint_state
;
94 void *velem_sint_state
;
95 void *velem_state_readbuf
;
100 /* Rasterizer state. */
102 void *rs_discard_state
;
104 /* Viewport state. */
105 struct pipe_viewport_state viewport
;
107 /* Destination surface dimensions. */
111 boolean has_geometry_shader
;
112 boolean vertex_has_integers
;
113 boolean has_stream_out
;
116 static void blitter_draw_rectangle(struct blitter_context
*blitter
,
117 unsigned x
, unsigned y
,
118 unsigned width
, unsigned height
,
120 enum blitter_attrib_type type
,
121 const union pipe_color_union
*attrib
);
124 struct blitter_context
*util_blitter_create(struct pipe_context
*pipe
)
126 struct blitter_context_priv
*ctx
;
127 struct pipe_blend_state blend
;
128 struct pipe_depth_stencil_alpha_state dsa
;
129 struct pipe_rasterizer_state rs_state
;
130 struct pipe_sampler_state sampler_state
;
131 struct pipe_vertex_element velem
[2];
134 ctx
= CALLOC_STRUCT(blitter_context_priv
);
138 ctx
->base
.pipe
= pipe
;
139 ctx
->base
.draw_rectangle
= blitter_draw_rectangle
;
141 /* init state objects for them to be considered invalid */
142 ctx
->base
.saved_blend_state
= INVALID_PTR
;
143 ctx
->base
.saved_dsa_state
= INVALID_PTR
;
144 ctx
->base
.saved_rs_state
= INVALID_PTR
;
145 ctx
->base
.saved_fs
= INVALID_PTR
;
146 ctx
->base
.saved_vs
= INVALID_PTR
;
147 ctx
->base
.saved_gs
= INVALID_PTR
;
148 ctx
->base
.saved_velem_state
= INVALID_PTR
;
149 ctx
->base
.saved_fb_state
.nr_cbufs
= ~0;
150 ctx
->base
.saved_num_sampler_views
= ~0;
151 ctx
->base
.saved_num_sampler_states
= ~0;
152 ctx
->base
.saved_num_vertex_buffers
= ~0;
153 ctx
->base
.saved_num_so_targets
= ~0;
155 ctx
->has_geometry_shader
=
156 pipe
->screen
->get_shader_param(pipe
->screen
, PIPE_SHADER_GEOMETRY
,
157 PIPE_SHADER_CAP_MAX_INSTRUCTIONS
) > 0;
158 ctx
->vertex_has_integers
=
159 pipe
->screen
->get_shader_param(pipe
->screen
, PIPE_SHADER_VERTEX
,
160 PIPE_SHADER_CAP_INTEGERS
);
161 ctx
->has_stream_out
=
162 pipe
->screen
->get_param(pipe
->screen
,
163 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
) != 0;
165 /* blend state objects */
166 memset(&blend
, 0, sizeof(blend
));
167 ctx
->blend_keep_color
= pipe
->create_blend_state(pipe
, &blend
);
169 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
170 ctx
->blend_write_color
= pipe
->create_blend_state(pipe
, &blend
);
172 /* depth stencil alpha state objects */
173 memset(&dsa
, 0, sizeof(dsa
));
174 ctx
->dsa_keep_depth_stencil
=
175 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
177 dsa
.depth
.enabled
= 1;
178 dsa
.depth
.writemask
= 1;
179 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
180 ctx
->dsa_write_depth_keep_stencil
=
181 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
183 dsa
.stencil
[0].enabled
= 1;
184 dsa
.stencil
[0].func
= PIPE_FUNC_ALWAYS
;
185 dsa
.stencil
[0].fail_op
= PIPE_STENCIL_OP_REPLACE
;
186 dsa
.stencil
[0].zpass_op
= PIPE_STENCIL_OP_REPLACE
;
187 dsa
.stencil
[0].zfail_op
= PIPE_STENCIL_OP_REPLACE
;
188 dsa
.stencil
[0].valuemask
= 0xff;
189 dsa
.stencil
[0].writemask
= 0xff;
190 ctx
->dsa_write_depth_stencil
=
191 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
193 dsa
.depth
.enabled
= 0;
194 dsa
.depth
.writemask
= 0;
195 ctx
->dsa_keep_depth_write_stencil
=
196 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
199 memset(&sampler_state
, 0, sizeof(sampler_state
));
200 sampler_state
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
201 sampler_state
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
202 sampler_state
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
203 sampler_state
.normalized_coords
= 1;
204 ctx
->sampler_state
= pipe
->create_sampler_state(pipe
, &sampler_state
);
206 /* rasterizer state */
207 memset(&rs_state
, 0, sizeof(rs_state
));
208 rs_state
.cull_face
= PIPE_FACE_NONE
;
209 rs_state
.gl_rasterization_rules
= 1;
210 rs_state
.flatshade
= 1;
211 rs_state
.depth_clip
= 1;
212 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
214 if (ctx
->has_stream_out
) {
215 rs_state
.rasterizer_discard
= 1;
216 ctx
->rs_discard_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
219 /* vertex elements states */
220 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
221 for (i
= 0; i
< 2; i
++) {
222 velem
[i
].src_offset
= i
* 4 * sizeof(float);
223 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
225 ctx
->velem_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
227 if (ctx
->vertex_has_integers
) {
228 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
229 velem
[0].src_offset
= 0;
230 velem
[0].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
231 velem
[1].src_offset
= 4 * sizeof(float);
232 velem
[1].src_format
= PIPE_FORMAT_R32G32B32A32_SINT
;
233 ctx
->velem_sint_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
235 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
236 velem
[0].src_offset
= 0;
237 velem
[0].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
238 velem
[1].src_offset
= 4 * sizeof(float);
239 velem
[1].src_format
= PIPE_FORMAT_R32G32B32A32_UINT
;
240 ctx
->velem_uint_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
243 if (ctx
->has_stream_out
) {
244 velem
[0].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
245 ctx
->velem_state_readbuf
= pipe
->create_vertex_elements_state(pipe
, 1, &velem
[0]);
248 /* fragment shaders are created on-demand */
252 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
253 TGSI_SEMANTIC_GENERIC
};
254 const uint semantic_indices
[] = { 0, 0 };
256 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
259 if (ctx
->has_stream_out
) {
260 struct pipe_stream_output_info so
;
261 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
};
262 const uint semantic_indices
[] = { 0 };
264 memset(&so
, 0, sizeof(so
));
266 so
.output
[0].register_mask
= TGSI_WRITEMASK_XYZW
;
270 util_make_vertex_passthrough_shader_with_so(pipe
, 1, semantic_names
,
271 semantic_indices
, &so
);
274 /* set invariant vertex coordinates */
275 for (i
= 0; i
< 4; i
++)
276 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
278 /* create the vertex buffer */
279 ctx
->vbuf
= pipe_user_buffer_create(ctx
->base
.pipe
->screen
,
281 sizeof(ctx
->vertices
),
282 PIPE_BIND_VERTEX_BUFFER
);
287 void util_blitter_destroy(struct blitter_context
*blitter
)
289 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
290 struct pipe_context
*pipe
= blitter
->pipe
;
293 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
294 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
295 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
296 pipe
->delete_depth_stencil_alpha_state(pipe
,
297 ctx
->dsa_write_depth_keep_stencil
);
298 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
299 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
301 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
302 if (ctx
->rs_discard_state
)
303 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_discard_state
);
304 pipe
->delete_vs_state(pipe
, ctx
->vs
);
305 if (ctx
->vs_pos_only
)
306 pipe
->delete_vs_state(pipe
, ctx
->vs_pos_only
);
307 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state
);
308 if (ctx
->vertex_has_integers
) {
309 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_sint_state
);
310 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_uint_state
);
312 if (ctx
->velem_state_readbuf
)
313 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state_readbuf
);
315 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
316 if (ctx
->fs_texfetch_col
[i
])
317 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
318 if (ctx
->fs_texfetch_depth
[i
])
319 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
322 for (i
= 0; i
<= PIPE_MAX_COLOR_BUFS
; i
++) {
324 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
325 if (ctx
->fs_col_int
[i
])
326 pipe
->delete_fs_state(pipe
, ctx
->fs_col_int
[i
]);
329 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
);
330 pipe_resource_reference(&ctx
->vbuf
, NULL
);
334 static void blitter_set_running_flag(struct blitter_context_priv
*ctx
)
336 if (ctx
->base
.running
) {
337 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
340 ctx
->base
.running
= TRUE
;
343 static void blitter_unset_running_flag(struct blitter_context_priv
*ctx
)
345 if (!ctx
->base
.running
) {
346 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
349 ctx
->base
.running
= FALSE
;
352 static void blitter_check_saved_vertex_states(struct blitter_context_priv
*ctx
)
354 assert(ctx
->base
.saved_num_vertex_buffers
!= ~0 &&
355 ctx
->base
.saved_velem_state
!= INVALID_PTR
&&
356 ctx
->base
.saved_vs
!= INVALID_PTR
&&
357 (!ctx
->has_geometry_shader
|| ctx
->base
.saved_gs
!= INVALID_PTR
) &&
358 (!ctx
->has_stream_out
|| ctx
->base
.saved_num_so_targets
!= ~0) &&
359 ctx
->base
.saved_rs_state
!= INVALID_PTR
);
362 static void blitter_restore_vertex_states(struct blitter_context_priv
*ctx
)
364 struct pipe_context
*pipe
= ctx
->base
.pipe
;
367 /* Vertex buffers. */
368 pipe
->set_vertex_buffers(pipe
,
369 ctx
->base
.saved_num_vertex_buffers
,
370 ctx
->base
.saved_vertex_buffers
);
372 for (i
= 0; i
< ctx
->base
.saved_num_vertex_buffers
; i
++) {
373 if (ctx
->base
.saved_vertex_buffers
[i
].buffer
) {
374 pipe_resource_reference(&ctx
->base
.saved_vertex_buffers
[i
].buffer
,
378 ctx
->base
.saved_num_vertex_buffers
= ~0;
380 /* Vertex elements. */
381 pipe
->bind_vertex_elements_state(pipe
, ctx
->base
.saved_velem_state
);
382 ctx
->base
.saved_velem_state
= INVALID_PTR
;
385 pipe
->bind_vs_state(pipe
, ctx
->base
.saved_vs
);
386 ctx
->base
.saved_vs
= INVALID_PTR
;
388 /* Geometry shader. */
389 if (ctx
->has_geometry_shader
) {
390 pipe
->bind_gs_state(pipe
, ctx
->base
.saved_gs
);
391 ctx
->base
.saved_gs
= INVALID_PTR
;
394 /* Stream outputs. */
395 if (ctx
->has_stream_out
) {
396 pipe
->set_stream_output_targets(pipe
,
397 ctx
->base
.saved_num_so_targets
,
398 ctx
->base
.saved_so_targets
, ~0);
400 for (i
= 0; i
< ctx
->base
.saved_num_so_targets
; i
++)
401 pipe_so_target_reference(&ctx
->base
.saved_so_targets
[i
], NULL
);
403 ctx
->base
.saved_num_so_targets
= ~0;
407 pipe
->bind_rasterizer_state(pipe
, ctx
->base
.saved_rs_state
);
408 ctx
->base
.saved_rs_state
= INVALID_PTR
;
411 static void blitter_check_saved_fragment_states(struct blitter_context_priv
*ctx
)
413 assert(ctx
->base
.saved_fs
!= INVALID_PTR
&&
414 ctx
->base
.saved_dsa_state
!= INVALID_PTR
&&
415 ctx
->base
.saved_blend_state
!= INVALID_PTR
);
418 static void blitter_restore_fragment_states(struct blitter_context_priv
*ctx
)
420 struct pipe_context
*pipe
= ctx
->base
.pipe
;
422 /* Fragment shader. */
423 pipe
->bind_fs_state(pipe
, ctx
->base
.saved_fs
);
424 ctx
->base
.saved_fs
= INVALID_PTR
;
426 /* Depth, stencil, alpha. */
427 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->base
.saved_dsa_state
);
428 ctx
->base
.saved_dsa_state
= INVALID_PTR
;
431 pipe
->bind_blend_state(pipe
, ctx
->base
.saved_blend_state
);
432 ctx
->base
.saved_blend_state
= INVALID_PTR
;
434 /* Miscellaneous states. */
435 /* XXX check whether these are saved and whether they need to be restored
436 * (depending on the operation) */
437 pipe
->set_stencil_ref(pipe
, &ctx
->base
.saved_stencil_ref
);
438 pipe
->set_viewport_state(pipe
, &ctx
->base
.saved_viewport
);
441 static void blitter_check_saved_fb_state(struct blitter_context_priv
*ctx
)
443 assert(ctx
->base
.saved_fb_state
.nr_cbufs
!= ~0);
446 static void blitter_restore_fb_state(struct blitter_context_priv
*ctx
)
448 struct pipe_context
*pipe
= ctx
->base
.pipe
;
450 pipe
->set_framebuffer_state(pipe
, &ctx
->base
.saved_fb_state
);
451 util_unreference_framebuffer_state(&ctx
->base
.saved_fb_state
);
454 static void blitter_check_saved_textures(struct blitter_context_priv
*ctx
)
456 assert(ctx
->base
.saved_num_sampler_states
!= ~0 &&
457 ctx
->base
.saved_num_sampler_views
!= ~0);
460 static void blitter_restore_textures(struct blitter_context_priv
*ctx
)
462 struct pipe_context
*pipe
= ctx
->base
.pipe
;
465 /* Fragment sampler states. */
466 pipe
->bind_fragment_sampler_states(pipe
,
467 ctx
->base
.saved_num_sampler_states
,
468 ctx
->base
.saved_sampler_states
);
469 ctx
->base
.saved_num_sampler_states
= ~0;
471 /* Fragment sampler views. */
472 pipe
->set_fragment_sampler_views(pipe
,
473 ctx
->base
.saved_num_sampler_views
,
474 ctx
->base
.saved_sampler_views
);
476 for (i
= 0; i
< ctx
->base
.saved_num_sampler_views
; i
++)
477 pipe_sampler_view_reference(&ctx
->base
.saved_sampler_views
[i
], NULL
);
479 ctx
->base
.saved_num_sampler_views
= ~0;
482 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
483 unsigned x1
, unsigned y1
,
484 unsigned x2
, unsigned y2
,
489 /* set vertex positions */
490 ctx
->vertices
[0][0][0] = (float)x1
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v0.x*/
491 ctx
->vertices
[0][0][1] = (float)y1
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v0.y*/
493 ctx
->vertices
[1][0][0] = (float)x2
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v1.x*/
494 ctx
->vertices
[1][0][1] = (float)y1
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v1.y*/
496 ctx
->vertices
[2][0][0] = (float)x2
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v2.x*/
497 ctx
->vertices
[2][0][1] = (float)y2
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v2.y*/
499 ctx
->vertices
[3][0][0] = (float)x1
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v3.x*/
500 ctx
->vertices
[3][0][1] = (float)y2
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v3.y*/
502 for (i
= 0; i
< 4; i
++)
503 ctx
->vertices
[i
][0][2] = depth
; /*z*/
506 ctx
->viewport
.scale
[0] = 0.5f
* ctx
->dst_width
;
507 ctx
->viewport
.scale
[1] = 0.5f
* ctx
->dst_height
;
508 ctx
->viewport
.scale
[2] = 1.0f
;
509 ctx
->viewport
.scale
[3] = 1.0f
;
510 ctx
->viewport
.translate
[0] = 0.5f
* ctx
->dst_width
;
511 ctx
->viewport
.translate
[1] = 0.5f
* ctx
->dst_height
;
512 ctx
->viewport
.translate
[2] = 0.0f
;
513 ctx
->viewport
.translate
[3] = 0.0f
;
514 ctx
->base
.pipe
->set_viewport_state(ctx
->base
.pipe
, &ctx
->viewport
);
517 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
518 const union pipe_color_union
*color
)
523 for (i
= 0; i
< 4; i
++) {
524 uint32_t *uiverts
= (uint32_t *)ctx
->vertices
[i
][1];
525 uiverts
[0] = color
->ui
[0];
526 uiverts
[1] = color
->ui
[1];
527 uiverts
[2] = color
->ui
[2];
528 uiverts
[3] = color
->ui
[3];
531 for (i
= 0; i
< 4; i
++) {
532 ctx
->vertices
[i
][1][0] = 0;
533 ctx
->vertices
[i
][1][1] = 0;
534 ctx
->vertices
[i
][1][2] = 0;
535 ctx
->vertices
[i
][1][3] = 0;
540 static void get_texcoords(struct pipe_sampler_view
*src
,
541 unsigned src_width0
, unsigned src_height0
,
542 unsigned x1
, unsigned y1
,
543 unsigned x2
, unsigned y2
,
546 struct pipe_resource
*tex
= src
->texture
;
547 unsigned level
= src
->u
.tex
.first_level
;
548 boolean normalized
= tex
->target
!= PIPE_TEXTURE_RECT
;
551 out
[0] = x1
/ (float)u_minify(src_width0
, level
);
552 out
[1] = y1
/ (float)u_minify(src_height0
, level
);
553 out
[2] = x2
/ (float)u_minify(src_width0
, level
);
554 out
[3] = y2
/ (float)u_minify(src_height0
, level
);
563 static void set_texcoords_in_vertices(const float coord
[4],
564 float *out
, unsigned stride
)
566 out
[0] = coord
[0]; /*t0.s*/
567 out
[1] = coord
[1]; /*t0.t*/
569 out
[0] = coord
[2]; /*t1.s*/
570 out
[1] = coord
[1]; /*t1.t*/
572 out
[0] = coord
[2]; /*t2.s*/
573 out
[1] = coord
[3]; /*t2.t*/
575 out
[0] = coord
[0]; /*t3.s*/
576 out
[1] = coord
[3]; /*t3.t*/
579 static void blitter_set_texcoords(struct blitter_context_priv
*ctx
,
580 struct pipe_sampler_view
*src
,
581 unsigned src_width0
, unsigned src_height0
,
583 unsigned x1
, unsigned y1
,
584 unsigned x2
, unsigned y2
)
588 float face_coord
[4][2];
590 get_texcoords(src
, src_width0
, src_height0
, x1
, y1
, x2
, y2
, coord
);
592 if (src
->texture
->target
== PIPE_TEXTURE_CUBE
) {
593 set_texcoords_in_vertices(coord
, &face_coord
[0][0], 2);
594 util_map_texcoords2d_onto_cubemap(layer
,
595 /* pointer, stride in floats */
596 &face_coord
[0][0], 2,
597 &ctx
->vertices
[0][1][0], 8);
599 set_texcoords_in_vertices(coord
, &ctx
->vertices
[0][1][0], 8);
603 switch (src
->texture
->target
) {
604 case PIPE_TEXTURE_3D
:
606 float r
= layer
/ (float)u_minify(src
->texture
->depth0
,
607 src
->u
.tex
.first_level
);
608 for (i
= 0; i
< 4; i
++)
609 ctx
->vertices
[i
][1][2] = r
; /*r*/
613 case PIPE_TEXTURE_1D_ARRAY
:
614 for (i
= 0; i
< 4; i
++)
615 ctx
->vertices
[i
][1][1] = layer
; /*t*/
618 case PIPE_TEXTURE_2D_ARRAY
:
619 for (i
= 0; i
< 4; i
++)
620 ctx
->vertices
[i
][1][2] = layer
; /*r*/
627 static void blitter_set_dst_dimensions(struct blitter_context_priv
*ctx
,
628 unsigned width
, unsigned height
)
630 ctx
->dst_width
= width
;
631 ctx
->dst_height
= height
;
635 void *blitter_get_fs_col(struct blitter_context_priv
*ctx
, unsigned num_cbufs
,
638 struct pipe_context
*pipe
= ctx
->base
.pipe
;
640 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
643 if (!ctx
->fs_col_int
[num_cbufs
])
644 ctx
->fs_col_int
[num_cbufs
] =
645 util_make_fragment_cloneinput_shader(pipe
, num_cbufs
,
646 TGSI_SEMANTIC_GENERIC
,
647 TGSI_INTERPOLATE_CONSTANT
);
648 return ctx
->fs_col_int
[num_cbufs
];
650 if (!ctx
->fs_col
[num_cbufs
])
651 ctx
->fs_col
[num_cbufs
] =
652 util_make_fragment_cloneinput_shader(pipe
, num_cbufs
,
653 TGSI_SEMANTIC_GENERIC
,
654 TGSI_INTERPOLATE_LINEAR
);
655 return ctx
->fs_col
[num_cbufs
];
659 /** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */
661 pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target
)
663 switch (pipe_tex_target
) {
664 case PIPE_TEXTURE_1D
:
665 return TGSI_TEXTURE_1D
;
666 case PIPE_TEXTURE_2D
:
667 return TGSI_TEXTURE_2D
;
668 case PIPE_TEXTURE_RECT
:
669 return TGSI_TEXTURE_RECT
;
670 case PIPE_TEXTURE_3D
:
671 return TGSI_TEXTURE_3D
;
672 case PIPE_TEXTURE_CUBE
:
673 return TGSI_TEXTURE_CUBE
;
674 case PIPE_TEXTURE_1D_ARRAY
:
675 return TGSI_TEXTURE_1D_ARRAY
;
676 case PIPE_TEXTURE_2D_ARRAY
:
677 return TGSI_TEXTURE_2D_ARRAY
;
679 assert(0 && "unexpected texture target");
680 return TGSI_TEXTURE_UNKNOWN
;
686 void *blitter_get_fs_texfetch_col(struct blitter_context_priv
*ctx
,
689 struct pipe_context
*pipe
= ctx
->base
.pipe
;
691 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
693 /* Create the fragment shader on-demand. */
694 if (!ctx
->fs_texfetch_col
[tex_target
]) {
695 unsigned tgsi_tex
= pipe_tex_to_tgsi_tex(tex_target
);
697 ctx
->fs_texfetch_col
[tex_target
] =
698 util_make_fragment_tex_shader(pipe
, tgsi_tex
, TGSI_INTERPOLATE_LINEAR
);
701 return ctx
->fs_texfetch_col
[tex_target
];
705 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv
*ctx
,
708 struct pipe_context
*pipe
= ctx
->base
.pipe
;
710 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
712 /* Create the fragment shader on-demand. */
713 if (!ctx
->fs_texfetch_depth
[tex_target
]) {
714 unsigned tgsi_tex
= pipe_tex_to_tgsi_tex(tex_target
);
716 ctx
->fs_texfetch_depth
[tex_target
] =
717 util_make_fragment_tex_shader_writedepth(pipe
, tgsi_tex
,
718 TGSI_INTERPOLATE_LINEAR
);
721 return ctx
->fs_texfetch_depth
[tex_target
];
724 static void blitter_draw_rectangle(struct blitter_context
*blitter
,
725 unsigned x1
, unsigned y1
,
726 unsigned x2
, unsigned y2
,
728 enum blitter_attrib_type type
,
729 const union pipe_color_union
*attrib
)
731 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
734 case UTIL_BLITTER_ATTRIB_COLOR
:
735 blitter_set_clear_color(ctx
, attrib
);
738 case UTIL_BLITTER_ATTRIB_TEXCOORD
:
739 set_texcoords_in_vertices(attrib
->f
, &ctx
->vertices
[0][1][0], 8);
745 blitter_set_rectangle(ctx
, x1
, y1
, x2
, y2
, depth
);
746 ctx
->base
.pipe
->redefine_user_buffer(ctx
->base
.pipe
, ctx
->vbuf
,
747 0, ctx
->vbuf
->width0
);
748 util_draw_vertex_buffer(ctx
->base
.pipe
, NULL
, ctx
->vbuf
, 0,
749 PIPE_PRIM_TRIANGLE_FAN
, 4, 2);
752 static void util_blitter_clear_custom(struct blitter_context
*blitter
,
753 unsigned width
, unsigned height
,
755 unsigned clear_buffers
,
756 enum pipe_format cbuf_format
,
757 const union pipe_color_union
*color
,
758 double depth
, unsigned stencil
,
759 void *custom_blend
, void *custom_dsa
)
761 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
762 struct pipe_context
*pipe
= ctx
->base
.pipe
;
763 struct pipe_stencil_ref sr
= { { 0 } };
764 boolean int_format
= util_format_is_pure_integer(cbuf_format
);
765 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
767 blitter_set_running_flag(ctx
);
768 blitter_check_saved_vertex_states(ctx
);
769 blitter_check_saved_fragment_states(ctx
);
773 pipe
->bind_blend_state(pipe
, custom_blend
);
774 } else if (clear_buffers
& PIPE_CLEAR_COLOR
) {
775 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
777 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
781 pipe
->bind_depth_stencil_alpha_state(pipe
, custom_dsa
);
782 } else if ((clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
783 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
784 } else if (clear_buffers
& PIPE_CLEAR_DEPTH
) {
785 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
786 } else if (clear_buffers
& PIPE_CLEAR_STENCIL
) {
787 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
789 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
792 sr
.ref_value
[0] = stencil
& 0xff;
793 pipe
->set_stencil_ref(pipe
, &sr
);
795 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
796 if (util_format_is_pure_sint(cbuf_format
)) {
797 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_sint_state
);
798 } else if (util_format_is_pure_uint(cbuf_format
)) {
799 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_uint_state
);
801 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
803 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, num_cbufs
, int_format
));
804 pipe
->bind_vs_state(pipe
, ctx
->vs
);
805 if (ctx
->has_geometry_shader
)
806 pipe
->bind_gs_state(pipe
, NULL
);
808 blitter_set_dst_dimensions(ctx
, width
, height
);
809 blitter
->draw_rectangle(blitter
, 0, 0, width
, height
, depth
,
810 UTIL_BLITTER_ATTRIB_COLOR
, color
);
812 blitter_restore_vertex_states(ctx
);
813 blitter_restore_fragment_states(ctx
);
814 blitter_unset_running_flag(ctx
);
817 void util_blitter_clear(struct blitter_context
*blitter
,
818 unsigned width
, unsigned height
,
820 unsigned clear_buffers
,
821 enum pipe_format cbuf_format
,
822 const union pipe_color_union
*color
,
823 double depth
, unsigned stencil
)
825 util_blitter_clear_custom(blitter
, width
, height
, num_cbufs
,
826 clear_buffers
, cbuf_format
, color
, depth
, stencil
,
830 void util_blitter_clear_depth_custom(struct blitter_context
*blitter
,
831 unsigned width
, unsigned height
,
832 double depth
, void *custom_dsa
)
834 static const union pipe_color_union color
;
835 util_blitter_clear_custom(blitter
, width
, height
, 0,
836 0, PIPE_FORMAT_NONE
, &color
, depth
, 0, NULL
, custom_dsa
);
840 boolean
is_overlap(unsigned sx1
, unsigned sx2
, unsigned sy1
, unsigned sy2
,
841 unsigned dx1
, unsigned dx2
, unsigned dy1
, unsigned dy2
)
843 return sx1
< dx2
&& sx2
> dx1
&& sy1
< dy2
&& sy2
> dy1
;
846 void util_blitter_default_dst_texture(struct pipe_surface
*dst_templ
,
847 struct pipe_resource
*dst
,
850 const struct pipe_box
*srcbox
)
852 memset(dst_templ
, 0, sizeof(*dst_templ
));
853 dst_templ
->format
= dst
->format
;
854 if (util_format_is_depth_or_stencil(dst
->format
)) {
855 dst_templ
->usage
= PIPE_BIND_DEPTH_STENCIL
;
857 dst_templ
->usage
= PIPE_BIND_RENDER_TARGET
;
859 dst_templ
->format
= util_format_linear(dst
->format
);
860 dst_templ
->u
.tex
.level
= dstlevel
;
861 dst_templ
->u
.tex
.first_layer
= dstz
;
862 dst_templ
->u
.tex
.last_layer
= dstz
+ srcbox
->depth
- 1;
865 void util_blitter_default_src_texture(struct pipe_sampler_view
*src_templ
,
866 struct pipe_resource
*src
,
869 memset(src_templ
, 0, sizeof(*src_templ
));
870 src_templ
->format
= util_format_linear(src
->format
);
871 src_templ
->u
.tex
.first_level
= srclevel
;
872 src_templ
->u
.tex
.last_level
= srclevel
;
873 src_templ
->u
.tex
.first_layer
= 0;
874 src_templ
->u
.tex
.last_layer
=
875 src
->target
== PIPE_TEXTURE_3D
? src
->depth0
- 1
876 : src
->array_size
- 1;
877 src_templ
->swizzle_r
= PIPE_SWIZZLE_RED
;
878 src_templ
->swizzle_g
= PIPE_SWIZZLE_GREEN
;
879 src_templ
->swizzle_b
= PIPE_SWIZZLE_BLUE
;
880 src_templ
->swizzle_a
= PIPE_SWIZZLE_ALPHA
;
883 void util_blitter_copy_texture(struct blitter_context
*blitter
,
884 struct pipe_resource
*dst
,
886 unsigned dstx
, unsigned dsty
, unsigned dstz
,
887 struct pipe_resource
*src
,
889 const struct pipe_box
*srcbox
,
890 boolean ignore_stencil
)
892 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
893 struct pipe_context
*pipe
= ctx
->base
.pipe
;
894 struct pipe_screen
*screen
= pipe
->screen
;
895 struct pipe_surface
*dst_view
, dst_templ
;
896 struct pipe_sampler_view src_templ
, *src_view
;
898 boolean is_stencil
, is_depth
;
900 /* Give up if textures are not set. */
905 assert(src
->target
< PIPE_MAX_TEXTURE_TYPES
);
907 /* Is this a ZS format? */
908 is_depth
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 0) != 0;
909 is_stencil
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 1) != 0;
911 if (is_depth
|| is_stencil
)
912 bind
= PIPE_BIND_DEPTH_STENCIL
;
914 bind
= PIPE_BIND_RENDER_TARGET
;
916 /* Check if we can sample from and render to the surfaces. */
917 /* (assuming copying a stencil buffer is not possible) */
918 if ((!ignore_stencil
&& is_stencil
) ||
919 !screen
->is_format_supported(screen
, dst
->format
, dst
->target
,
920 dst
->nr_samples
, bind
) ||
921 !screen
->is_format_supported(screen
, src
->format
, src
->target
,
922 src
->nr_samples
, PIPE_BIND_SAMPLER_VIEW
)) {
923 blitter_set_running_flag(ctx
);
924 util_resource_copy_region(pipe
, dst
, dstlevel
, dstx
, dsty
, dstz
,
925 src
, srclevel
, srcbox
);
926 blitter_unset_running_flag(ctx
);
930 /* Initialize the surface. */
931 util_blitter_default_dst_texture(&dst_templ
, dst
, dstlevel
, dstz
, srcbox
);
932 dst_view
= pipe
->create_surface(pipe
, dst
, &dst_templ
);
934 /* Initialize the sampler view. */
935 util_blitter_default_src_texture(&src_templ
, src
, srclevel
);
936 src_view
= pipe
->create_sampler_view(pipe
, src
, &src_templ
);
939 util_blitter_copy_texture_view(blitter
, dst_view
, dstx
, dsty
, src_view
,
940 srcbox
, src
->width0
, src
->height0
);
942 pipe_surface_reference(&dst_view
, NULL
);
943 pipe_sampler_view_reference(&src_view
, NULL
);
946 void util_blitter_copy_texture_view(struct blitter_context
*blitter
,
947 struct pipe_surface
*dst
,
948 unsigned dstx
, unsigned dsty
,
949 struct pipe_sampler_view
*src
,
950 const struct pipe_box
*srcbox
,
951 unsigned src_width0
, unsigned src_height0
)
953 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
954 struct pipe_context
*pipe
= ctx
->base
.pipe
;
955 struct pipe_framebuffer_state fb_state
;
956 enum pipe_texture_target src_target
= src
->texture
->target
;
957 unsigned width
= srcbox
->width
;
958 unsigned height
= srcbox
->height
;
961 if (dst
->texture
== src
->texture
&&
962 dst
->u
.tex
.level
== src
->u
.tex
.first_level
) {
963 assert(!is_overlap(srcbox
->x
, srcbox
->x
+ width
, srcbox
->y
, srcbox
->y
+ height
,
964 dstx
, dstx
+ width
, dsty
, dsty
+ height
));
966 /* XXX should handle 3d regions */
967 assert(srcbox
->depth
== 1);
969 /* Check whether the states are properly saved. */
970 blitter_set_running_flag(ctx
);
971 blitter_check_saved_vertex_states(ctx
);
972 blitter_check_saved_fragment_states(ctx
);
973 blitter_check_saved_textures(ctx
);
974 blitter_check_saved_fb_state(ctx
);
976 /* Initialize framebuffer state. */
977 fb_state
.width
= dst
->width
;
978 fb_state
.height
= dst
->height
;
980 if (util_format_is_depth_or_stencil(dst
->format
)) {
981 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
982 pipe
->bind_depth_stencil_alpha_state(pipe
,
983 ctx
->dsa_write_depth_keep_stencil
);
984 pipe
->bind_fs_state(pipe
,
985 blitter_get_fs_texfetch_depth(ctx
, src_target
));
987 fb_state
.nr_cbufs
= 0;
988 fb_state
.zsbuf
= dst
;
990 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
991 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
992 pipe
->bind_fs_state(pipe
,
993 blitter_get_fs_texfetch_col(ctx
, src_target
));
995 fb_state
.nr_cbufs
= 1;
996 fb_state
.cbufs
[0] = dst
;
1000 /* Set rasterizer state, shaders, and textures. */
1001 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
1002 pipe
->bind_vs_state(pipe
, ctx
->vs
);
1003 if (ctx
->has_geometry_shader
)
1004 pipe
->bind_gs_state(pipe
, NULL
);
1005 pipe
->bind_fragment_sampler_states(pipe
, 1, &ctx
->sampler_state
);
1006 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1007 pipe
->set_fragment_sampler_views(pipe
, 1, &src
);
1008 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1010 blitter_set_dst_dimensions(ctx
, dst
->width
, dst
->height
);
1012 switch (src_target
) {
1013 /* Draw the quad with the draw_rectangle callback. */
1014 case PIPE_TEXTURE_1D
:
1015 case PIPE_TEXTURE_2D
:
1016 case PIPE_TEXTURE_RECT
:
1018 /* Set texture coordinates. - use a pipe color union
1019 * for interface purposes.
1020 * XXX pipe_color_union is a wrong name since we use that to set
1021 * texture coordinates too.
1023 union pipe_color_union coord
;
1024 get_texcoords(src
, src_width0
, src_height0
, srcbox
->x
, srcbox
->y
,
1025 srcbox
->x
+width
, srcbox
->y
+height
, coord
.f
);
1028 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0,
1029 UTIL_BLITTER_ATTRIB_TEXCOORD
, &coord
);
1033 /* Draw the quad with the generic codepath. */
1035 /* Set texture coordinates. */
1036 switch (src_target
) {
1037 case PIPE_TEXTURE_1D_ARRAY
:
1038 case PIPE_TEXTURE_2D_ARRAY
:
1039 case PIPE_TEXTURE_3D
:
1040 case PIPE_TEXTURE_CUBE
:
1041 blitter_set_texcoords(ctx
, src
, src_width0
, src_height0
, srcbox
->z
,
1042 srcbox
->y
, srcbox
->x
,
1043 srcbox
->x
+ width
, srcbox
->y
+ height
);
1051 blitter_set_rectangle(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0);
1052 ctx
->base
.pipe
->redefine_user_buffer(ctx
->base
.pipe
, ctx
->vbuf
,
1053 0, ctx
->vbuf
->width0
);
1054 util_draw_vertex_buffer(ctx
->base
.pipe
, NULL
, ctx
->vbuf
, 0,
1055 PIPE_PRIM_TRIANGLE_FAN
, 4, 2);
1059 blitter_restore_vertex_states(ctx
);
1060 blitter_restore_fragment_states(ctx
);
1061 blitter_restore_textures(ctx
);
1062 blitter_restore_fb_state(ctx
);
1063 blitter_unset_running_flag(ctx
);
1066 /* Clear a region of a color surface to a constant value. */
1067 void util_blitter_clear_render_target(struct blitter_context
*blitter
,
1068 struct pipe_surface
*dstsurf
,
1069 const union pipe_color_union
*color
,
1070 unsigned dstx
, unsigned dsty
,
1071 unsigned width
, unsigned height
)
1073 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1074 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1075 struct pipe_framebuffer_state fb_state
;
1077 assert(dstsurf
->texture
);
1078 if (!dstsurf
->texture
)
1081 /* check the saved state */
1082 blitter_set_running_flag(ctx
);
1083 blitter_check_saved_vertex_states(ctx
);
1084 blitter_check_saved_fragment_states(ctx
);
1085 blitter_check_saved_fb_state(ctx
);
1088 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
1089 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
1090 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
1091 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 1, FALSE
));
1092 pipe
->bind_vs_state(pipe
, ctx
->vs
);
1093 if (ctx
->has_geometry_shader
)
1094 pipe
->bind_gs_state(pipe
, NULL
);
1095 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1097 /* set a framebuffer state */
1098 fb_state
.width
= dstsurf
->width
;
1099 fb_state
.height
= dstsurf
->height
;
1100 fb_state
.nr_cbufs
= 1;
1101 fb_state
.cbufs
[0] = dstsurf
;
1103 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1105 blitter_set_dst_dimensions(ctx
, dstsurf
->width
, dstsurf
->height
);
1106 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0,
1107 UTIL_BLITTER_ATTRIB_COLOR
, color
);
1109 blitter_restore_vertex_states(ctx
);
1110 blitter_restore_fragment_states(ctx
);
1111 blitter_restore_fb_state(ctx
);
1112 blitter_unset_running_flag(ctx
);
1115 /* Clear a region of a depth stencil surface. */
1116 void util_blitter_clear_depth_stencil(struct blitter_context
*blitter
,
1117 struct pipe_surface
*dstsurf
,
1118 unsigned clear_flags
,
1121 unsigned dstx
, unsigned dsty
,
1122 unsigned width
, unsigned height
)
1124 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1125 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1126 struct pipe_framebuffer_state fb_state
;
1127 struct pipe_stencil_ref sr
= { { 0 } };
1129 assert(dstsurf
->texture
);
1130 if (!dstsurf
->texture
)
1133 /* check the saved state */
1134 blitter_set_running_flag(ctx
);
1135 blitter_check_saved_vertex_states(ctx
);
1136 blitter_check_saved_fragment_states(ctx
);
1137 blitter_check_saved_fb_state(ctx
);
1140 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
1141 if ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
1142 sr
.ref_value
[0] = stencil
& 0xff;
1143 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
1144 pipe
->set_stencil_ref(pipe
, &sr
);
1146 else if (clear_flags
& PIPE_CLEAR_DEPTH
) {
1147 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
1149 else if (clear_flags
& PIPE_CLEAR_STENCIL
) {
1150 sr
.ref_value
[0] = stencil
& 0xff;
1151 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
1152 pipe
->set_stencil_ref(pipe
, &sr
);
1155 /* hmm that should be illegal probably, or make it a no-op somewhere */
1156 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
1158 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
1159 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 0, FALSE
));
1160 pipe
->bind_vs_state(pipe
, ctx
->vs
);
1161 if (ctx
->has_geometry_shader
)
1162 pipe
->bind_gs_state(pipe
, NULL
);
1163 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1165 /* set a framebuffer state */
1166 fb_state
.width
= dstsurf
->width
;
1167 fb_state
.height
= dstsurf
->height
;
1168 fb_state
.nr_cbufs
= 0;
1169 fb_state
.cbufs
[0] = 0;
1170 fb_state
.zsbuf
= dstsurf
;
1171 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1173 blitter_set_dst_dimensions(ctx
, dstsurf
->width
, dstsurf
->height
);
1174 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, depth
,
1175 UTIL_BLITTER_ATTRIB_NONE
, NULL
);
1177 blitter_restore_vertex_states(ctx
);
1178 blitter_restore_fragment_states(ctx
);
1179 blitter_restore_fb_state(ctx
);
1180 blitter_unset_running_flag(ctx
);
1183 /* draw a rectangle across a region using a custom dsa stage - for r600g */
1184 void util_blitter_custom_depth_stencil(struct blitter_context
*blitter
,
1185 struct pipe_surface
*zsurf
,
1186 struct pipe_surface
*cbsurf
,
1187 void *dsa_stage
, float depth
)
1189 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1190 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1191 struct pipe_framebuffer_state fb_state
;
1193 assert(zsurf
->texture
);
1194 if (!zsurf
->texture
)
1197 /* check the saved state */
1198 blitter_set_running_flag(ctx
);
1199 blitter_check_saved_vertex_states(ctx
);
1200 blitter_check_saved_fragment_states(ctx
);
1201 blitter_check_saved_fb_state(ctx
);
1204 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
1205 pipe
->bind_depth_stencil_alpha_state(pipe
, dsa_stage
);
1207 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
1208 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 0, FALSE
));
1209 pipe
->bind_vs_state(pipe
, ctx
->vs
);
1210 if (ctx
->has_geometry_shader
)
1211 pipe
->bind_gs_state(pipe
, NULL
);
1212 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1214 /* set a framebuffer state */
1215 fb_state
.width
= zsurf
->width
;
1216 fb_state
.height
= zsurf
->height
;
1217 fb_state
.nr_cbufs
= 1;
1219 fb_state
.cbufs
[0] = cbsurf
;
1220 fb_state
.nr_cbufs
= 1;
1222 fb_state
.cbufs
[0] = NULL
;
1223 fb_state
.nr_cbufs
= 0;
1225 fb_state
.zsbuf
= zsurf
;
1226 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1228 blitter_set_dst_dimensions(ctx
, zsurf
->width
, zsurf
->height
);
1229 blitter
->draw_rectangle(blitter
, 0, 0, zsurf
->width
, zsurf
->height
, depth
,
1230 UTIL_BLITTER_ATTRIB_NONE
, NULL
);
1232 blitter_restore_vertex_states(ctx
);
1233 blitter_restore_fragment_states(ctx
);
1234 blitter_restore_fb_state(ctx
);
1235 blitter_unset_running_flag(ctx
);
1238 void util_blitter_copy_buffer(struct blitter_context
*blitter
,
1239 struct pipe_resource
*dst
,
1241 struct pipe_resource
*src
,
1245 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1246 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1247 struct pipe_vertex_buffer vb
;
1248 struct pipe_stream_output_target
*so_target
;
1250 /* Drivers not capable of Stream Out should not call this function
1251 * in the first place. */
1252 assert(ctx
->has_stream_out
);
1254 /* Some alignment is required. */
1255 if (srcx
% 4 != 0 || dstx
% 4 != 0 || size
% 16 != 0 ||
1256 !ctx
->has_stream_out
) {
1257 struct pipe_box box
;
1258 u_box_1d(srcx
, size
, &box
);
1259 util_resource_copy_region(pipe
, dst
, 0, dstx
, 0, 0, src
, 0, &box
);
1263 blitter_set_running_flag(ctx
);
1264 blitter_check_saved_vertex_states(ctx
);
1267 vb
.buffer_offset
= srcx
;
1270 pipe
->set_vertex_buffers(pipe
, 1, &vb
);
1271 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state_readbuf
);
1272 pipe
->bind_vs_state(pipe
, ctx
->vs_pos_only
);
1273 if (ctx
->has_geometry_shader
)
1274 pipe
->bind_gs_state(pipe
, NULL
);
1275 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_discard_state
);
1277 so_target
= pipe
->create_stream_output_target(pipe
, dst
, dstx
, size
);
1278 pipe
->set_stream_output_targets(pipe
, 1, &so_target
, 0);
1280 util_draw_arrays(pipe
, PIPE_PRIM_POINTS
, 0, size
/ 16);
1282 blitter_restore_vertex_states(ctx
);
1283 blitter_unset_running_flag(ctx
);
1284 pipe_so_target_reference(&so_target
, NULL
);