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"
50 #include "util/u_upload_mgr.h"
52 #define INVALID_PTR ((void*)~0)
54 struct blitter_context_priv
56 struct blitter_context base
;
58 struct u_upload_mgr
*upload
;
60 float vertices
[4][2][4]; /**< {pos, color} or {pos, texcoord} */
62 /* Templates for various state objects. */
64 /* Constant state objects. */
66 void *vs
; /**< Vertex shader which passes {pos, generic} to the output.*/
67 void *vs_pos_only
; /**< Vertex shader which passes pos to the output.*/
69 /* Fragment shaders. */
70 /* The shader at index i outputs color to color buffers 0,1,...,i-1. */
71 void *fs_col
[PIPE_MAX_COLOR_BUFS
+1];
72 void *fs_col_int
[PIPE_MAX_COLOR_BUFS
+1];
74 /* FS which outputs a color from a texture,
75 where the index is PIPE_TEXTURE_* to be sampled. */
76 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
78 /* FS which outputs a depth from a texture,
79 where the index is PIPE_TEXTURE_* to be sampled. */
80 void *fs_texfetch_depth
[PIPE_MAX_TEXTURE_TYPES
];
81 void *fs_texfetch_depthstencil
[PIPE_MAX_TEXTURE_TYPES
];
82 void *fs_texfetch_stencil
[PIPE_MAX_TEXTURE_TYPES
];
85 void *blend_write_color
; /**< blend state with writemask of RGBA */
86 void *blend_keep_color
; /**< blend state with writemask of 0 */
88 /* Depth stencil alpha state. */
89 void *dsa_write_depth_stencil
;
90 void *dsa_write_depth_keep_stencil
;
91 void *dsa_keep_depth_stencil
;
92 void *dsa_keep_depth_write_stencil
;
94 /* Vertex elements states. */
96 void *velem_uint_state
;
97 void *velem_sint_state
;
98 void *velem_state_readbuf
;
103 /* Rasterizer state. */
105 void *rs_discard_state
;
107 /* Viewport state. */
108 struct pipe_viewport_state viewport
;
110 /* Destination surface dimensions. */
114 boolean has_geometry_shader
;
115 boolean vertex_has_integers
;
116 boolean has_stream_out
;
117 boolean has_stencil_export
;
120 static void blitter_draw_rectangle(struct blitter_context
*blitter
,
121 unsigned x
, unsigned y
,
122 unsigned width
, unsigned height
,
124 enum blitter_attrib_type type
,
125 const union pipe_color_union
*attrib
);
128 struct blitter_context
*util_blitter_create(struct pipe_context
*pipe
)
130 struct blitter_context_priv
*ctx
;
131 struct pipe_blend_state blend
;
132 struct pipe_depth_stencil_alpha_state dsa
;
133 struct pipe_rasterizer_state rs_state
;
134 struct pipe_sampler_state sampler_state
;
135 struct pipe_vertex_element velem
[2];
138 ctx
= CALLOC_STRUCT(blitter_context_priv
);
142 ctx
->base
.pipe
= pipe
;
143 ctx
->base
.draw_rectangle
= blitter_draw_rectangle
;
145 /* init state objects for them to be considered invalid */
146 ctx
->base
.saved_blend_state
= INVALID_PTR
;
147 ctx
->base
.saved_dsa_state
= INVALID_PTR
;
148 ctx
->base
.saved_rs_state
= INVALID_PTR
;
149 ctx
->base
.saved_fs
= INVALID_PTR
;
150 ctx
->base
.saved_vs
= INVALID_PTR
;
151 ctx
->base
.saved_gs
= INVALID_PTR
;
152 ctx
->base
.saved_velem_state
= INVALID_PTR
;
153 ctx
->base
.saved_fb_state
.nr_cbufs
= ~0;
154 ctx
->base
.saved_num_sampler_views
= ~0;
155 ctx
->base
.saved_num_sampler_states
= ~0;
156 ctx
->base
.saved_num_vertex_buffers
= ~0;
157 ctx
->base
.saved_num_so_targets
= ~0;
159 ctx
->has_geometry_shader
=
160 pipe
->screen
->get_shader_param(pipe
->screen
, PIPE_SHADER_GEOMETRY
,
161 PIPE_SHADER_CAP_MAX_INSTRUCTIONS
) > 0;
162 ctx
->vertex_has_integers
=
163 pipe
->screen
->get_shader_param(pipe
->screen
, PIPE_SHADER_VERTEX
,
164 PIPE_SHADER_CAP_INTEGERS
);
165 ctx
->has_stream_out
=
166 pipe
->screen
->get_param(pipe
->screen
,
167 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS
) != 0;
169 ctx
->has_stencil_export
=
170 pipe
->screen
->get_param(pipe
->screen
,
171 PIPE_CAP_SHADER_STENCIL_EXPORT
);
173 /* blend state objects */
174 memset(&blend
, 0, sizeof(blend
));
175 ctx
->blend_keep_color
= pipe
->create_blend_state(pipe
, &blend
);
177 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
178 ctx
->blend_write_color
= pipe
->create_blend_state(pipe
, &blend
);
180 /* depth stencil alpha state objects */
181 memset(&dsa
, 0, sizeof(dsa
));
182 ctx
->dsa_keep_depth_stencil
=
183 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
185 dsa
.depth
.enabled
= 1;
186 dsa
.depth
.writemask
= 1;
187 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
188 ctx
->dsa_write_depth_keep_stencil
=
189 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
191 dsa
.stencil
[0].enabled
= 1;
192 dsa
.stencil
[0].func
= PIPE_FUNC_ALWAYS
;
193 dsa
.stencil
[0].fail_op
= PIPE_STENCIL_OP_REPLACE
;
194 dsa
.stencil
[0].zpass_op
= PIPE_STENCIL_OP_REPLACE
;
195 dsa
.stencil
[0].zfail_op
= PIPE_STENCIL_OP_REPLACE
;
196 dsa
.stencil
[0].valuemask
= 0xff;
197 dsa
.stencil
[0].writemask
= 0xff;
198 ctx
->dsa_write_depth_stencil
=
199 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
201 dsa
.depth
.enabled
= 0;
202 dsa
.depth
.writemask
= 0;
203 ctx
->dsa_keep_depth_write_stencil
=
204 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
207 memset(&sampler_state
, 0, sizeof(sampler_state
));
208 sampler_state
.wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
209 sampler_state
.wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
210 sampler_state
.wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
211 sampler_state
.normalized_coords
= 1;
212 ctx
->sampler_state
= pipe
->create_sampler_state(pipe
, &sampler_state
);
214 /* rasterizer state */
215 memset(&rs_state
, 0, sizeof(rs_state
));
216 rs_state
.cull_face
= PIPE_FACE_NONE
;
217 rs_state
.gl_rasterization_rules
= 1;
218 rs_state
.flatshade
= 1;
219 rs_state
.depth_clip
= 1;
220 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
222 if (ctx
->has_stream_out
) {
223 rs_state
.rasterizer_discard
= 1;
224 ctx
->rs_discard_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
227 /* vertex elements states */
228 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
229 for (i
= 0; i
< 2; i
++) {
230 velem
[i
].src_offset
= i
* 4 * sizeof(float);
231 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
233 ctx
->velem_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
235 if (ctx
->vertex_has_integers
) {
236 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
237 velem
[0].src_offset
= 0;
238 velem
[0].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
239 velem
[1].src_offset
= 4 * sizeof(float);
240 velem
[1].src_format
= PIPE_FORMAT_R32G32B32A32_SINT
;
241 ctx
->velem_sint_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
243 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
244 velem
[0].src_offset
= 0;
245 velem
[0].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
246 velem
[1].src_offset
= 4 * sizeof(float);
247 velem
[1].src_format
= PIPE_FORMAT_R32G32B32A32_UINT
;
248 ctx
->velem_uint_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
251 if (ctx
->has_stream_out
) {
252 velem
[0].src_format
= PIPE_FORMAT_R32_UINT
;
253 ctx
->velem_state_readbuf
= pipe
->create_vertex_elements_state(pipe
, 1, &velem
[0]);
256 /* fragment shaders are created on-demand */
260 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
261 TGSI_SEMANTIC_GENERIC
};
262 const uint semantic_indices
[] = { 0, 0 };
264 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
267 if (ctx
->has_stream_out
) {
268 struct pipe_stream_output_info so
;
269 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
};
270 const uint semantic_indices
[] = { 0 };
272 memset(&so
, 0, sizeof(so
));
274 so
.output
[0].num_components
= 1;
278 util_make_vertex_passthrough_shader_with_so(pipe
, 1, semantic_names
,
279 semantic_indices
, &so
);
282 /* set invariant vertex coordinates */
283 for (i
= 0; i
< 4; i
++)
284 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
286 ctx
->upload
= u_upload_create(pipe
, 65536, 4, PIPE_BIND_VERTEX_BUFFER
);
291 void util_blitter_destroy(struct blitter_context
*blitter
)
293 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
294 struct pipe_context
*pipe
= blitter
->pipe
;
297 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
298 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
299 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
300 pipe
->delete_depth_stencil_alpha_state(pipe
,
301 ctx
->dsa_write_depth_keep_stencil
);
302 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
303 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
305 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
306 if (ctx
->rs_discard_state
)
307 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_discard_state
);
308 pipe
->delete_vs_state(pipe
, ctx
->vs
);
309 if (ctx
->vs_pos_only
)
310 pipe
->delete_vs_state(pipe
, ctx
->vs_pos_only
);
311 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state
);
312 if (ctx
->vertex_has_integers
) {
313 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_sint_state
);
314 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_uint_state
);
316 if (ctx
->velem_state_readbuf
)
317 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state_readbuf
);
319 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
320 if (ctx
->fs_texfetch_col
[i
])
321 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
322 if (ctx
->fs_texfetch_depth
[i
])
323 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
324 if (ctx
->fs_texfetch_depthstencil
[i
])
325 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depthstencil
[i
]);
326 if (ctx
->fs_texfetch_stencil
[i
])
327 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_stencil
[i
]);
330 for (i
= 0; i
<= PIPE_MAX_COLOR_BUFS
; i
++) {
332 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
333 if (ctx
->fs_col_int
[i
])
334 pipe
->delete_fs_state(pipe
, ctx
->fs_col_int
[i
]);
337 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
);
338 u_upload_destroy(ctx
->upload
);
342 static void blitter_set_running_flag(struct blitter_context_priv
*ctx
)
344 if (ctx
->base
.running
) {
345 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
348 ctx
->base
.running
= TRUE
;
351 static void blitter_unset_running_flag(struct blitter_context_priv
*ctx
)
353 if (!ctx
->base
.running
) {
354 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
357 ctx
->base
.running
= FALSE
;
360 static void blitter_check_saved_vertex_states(struct blitter_context_priv
*ctx
)
362 assert(ctx
->base
.saved_num_vertex_buffers
!= ~0);
363 assert(ctx
->base
.saved_velem_state
!= INVALID_PTR
);
364 assert(ctx
->base
.saved_vs
!= INVALID_PTR
);
365 assert(!ctx
->has_geometry_shader
|| ctx
->base
.saved_gs
!= INVALID_PTR
);
366 assert(!ctx
->has_stream_out
|| ctx
->base
.saved_num_so_targets
!= ~0);
367 assert(ctx
->base
.saved_rs_state
!= INVALID_PTR
);
370 static void blitter_restore_vertex_states(struct blitter_context_priv
*ctx
)
372 struct pipe_context
*pipe
= ctx
->base
.pipe
;
375 /* Vertex buffers. */
376 pipe
->set_vertex_buffers(pipe
,
377 ctx
->base
.saved_num_vertex_buffers
,
378 ctx
->base
.saved_vertex_buffers
);
380 for (i
= 0; i
< ctx
->base
.saved_num_vertex_buffers
; i
++) {
381 if (ctx
->base
.saved_vertex_buffers
[i
].buffer
) {
382 pipe_resource_reference(&ctx
->base
.saved_vertex_buffers
[i
].buffer
,
386 ctx
->base
.saved_num_vertex_buffers
= ~0;
388 /* Vertex elements. */
389 pipe
->bind_vertex_elements_state(pipe
, ctx
->base
.saved_velem_state
);
390 ctx
->base
.saved_velem_state
= INVALID_PTR
;
393 pipe
->bind_vs_state(pipe
, ctx
->base
.saved_vs
);
394 ctx
->base
.saved_vs
= INVALID_PTR
;
396 /* Geometry shader. */
397 if (ctx
->has_geometry_shader
) {
398 pipe
->bind_gs_state(pipe
, ctx
->base
.saved_gs
);
399 ctx
->base
.saved_gs
= INVALID_PTR
;
402 /* Stream outputs. */
403 if (ctx
->has_stream_out
) {
404 pipe
->set_stream_output_targets(pipe
,
405 ctx
->base
.saved_num_so_targets
,
406 ctx
->base
.saved_so_targets
, ~0);
408 for (i
= 0; i
< ctx
->base
.saved_num_so_targets
; i
++)
409 pipe_so_target_reference(&ctx
->base
.saved_so_targets
[i
], NULL
);
411 ctx
->base
.saved_num_so_targets
= ~0;
415 pipe
->bind_rasterizer_state(pipe
, ctx
->base
.saved_rs_state
);
416 ctx
->base
.saved_rs_state
= INVALID_PTR
;
419 static void blitter_check_saved_fragment_states(struct blitter_context_priv
*ctx
)
421 assert(ctx
->base
.saved_fs
!= INVALID_PTR
);
422 assert(ctx
->base
.saved_dsa_state
!= INVALID_PTR
);
423 assert(ctx
->base
.saved_blend_state
!= INVALID_PTR
);
426 static void blitter_restore_fragment_states(struct blitter_context_priv
*ctx
)
428 struct pipe_context
*pipe
= ctx
->base
.pipe
;
430 /* Fragment shader. */
431 pipe
->bind_fs_state(pipe
, ctx
->base
.saved_fs
);
432 ctx
->base
.saved_fs
= INVALID_PTR
;
434 /* Depth, stencil, alpha. */
435 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->base
.saved_dsa_state
);
436 ctx
->base
.saved_dsa_state
= INVALID_PTR
;
439 pipe
->bind_blend_state(pipe
, ctx
->base
.saved_blend_state
);
440 ctx
->base
.saved_blend_state
= INVALID_PTR
;
443 if (ctx
->base
.is_sample_mask_saved
) {
444 pipe
->set_sample_mask(pipe
, ctx
->base
.saved_sample_mask
);
445 ctx
->base
.is_sample_mask_saved
= FALSE
;
448 /* Miscellaneous states. */
449 /* XXX check whether these are saved and whether they need to be restored
450 * (depending on the operation) */
451 pipe
->set_stencil_ref(pipe
, &ctx
->base
.saved_stencil_ref
);
452 pipe
->set_viewport_state(pipe
, &ctx
->base
.saved_viewport
);
455 static void blitter_check_saved_fb_state(struct blitter_context_priv
*ctx
)
457 assert(ctx
->base
.saved_fb_state
.nr_cbufs
!= ~0);
460 static void blitter_restore_fb_state(struct blitter_context_priv
*ctx
)
462 struct pipe_context
*pipe
= ctx
->base
.pipe
;
464 pipe
->set_framebuffer_state(pipe
, &ctx
->base
.saved_fb_state
);
465 util_unreference_framebuffer_state(&ctx
->base
.saved_fb_state
);
468 static void blitter_check_saved_textures(struct blitter_context_priv
*ctx
)
470 assert(ctx
->base
.saved_num_sampler_states
!= ~0);
471 assert(ctx
->base
.saved_num_sampler_views
!= ~0);
474 static void blitter_restore_textures(struct blitter_context_priv
*ctx
)
476 struct pipe_context
*pipe
= ctx
->base
.pipe
;
479 /* Fragment sampler states. */
480 pipe
->bind_fragment_sampler_states(pipe
,
481 ctx
->base
.saved_num_sampler_states
,
482 ctx
->base
.saved_sampler_states
);
483 ctx
->base
.saved_num_sampler_states
= ~0;
485 /* Fragment sampler views. */
486 pipe
->set_fragment_sampler_views(pipe
,
487 ctx
->base
.saved_num_sampler_views
,
488 ctx
->base
.saved_sampler_views
);
490 for (i
= 0; i
< ctx
->base
.saved_num_sampler_views
; i
++)
491 pipe_sampler_view_reference(&ctx
->base
.saved_sampler_views
[i
], NULL
);
493 ctx
->base
.saved_num_sampler_views
= ~0;
496 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
497 unsigned x1
, unsigned y1
,
498 unsigned x2
, unsigned y2
,
503 /* set vertex positions */
504 ctx
->vertices
[0][0][0] = (float)x1
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v0.x*/
505 ctx
->vertices
[0][0][1] = (float)y1
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v0.y*/
507 ctx
->vertices
[1][0][0] = (float)x2
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v1.x*/
508 ctx
->vertices
[1][0][1] = (float)y1
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v1.y*/
510 ctx
->vertices
[2][0][0] = (float)x2
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v2.x*/
511 ctx
->vertices
[2][0][1] = (float)y2
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v2.y*/
513 ctx
->vertices
[3][0][0] = (float)x1
/ ctx
->dst_width
* 2.0f
- 1.0f
; /*v3.x*/
514 ctx
->vertices
[3][0][1] = (float)y2
/ ctx
->dst_height
* 2.0f
- 1.0f
; /*v3.y*/
516 for (i
= 0; i
< 4; i
++)
517 ctx
->vertices
[i
][0][2] = depth
; /*z*/
520 ctx
->viewport
.scale
[0] = 0.5f
* ctx
->dst_width
;
521 ctx
->viewport
.scale
[1] = 0.5f
* ctx
->dst_height
;
522 ctx
->viewport
.scale
[2] = 1.0f
;
523 ctx
->viewport
.scale
[3] = 1.0f
;
524 ctx
->viewport
.translate
[0] = 0.5f
* ctx
->dst_width
;
525 ctx
->viewport
.translate
[1] = 0.5f
* ctx
->dst_height
;
526 ctx
->viewport
.translate
[2] = 0.0f
;
527 ctx
->viewport
.translate
[3] = 0.0f
;
528 ctx
->base
.pipe
->set_viewport_state(ctx
->base
.pipe
, &ctx
->viewport
);
531 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
532 const union pipe_color_union
*color
)
537 for (i
= 0; i
< 4; i
++) {
538 uint32_t *uiverts
= (uint32_t *)ctx
->vertices
[i
][1];
539 uiverts
[0] = color
->ui
[0];
540 uiverts
[1] = color
->ui
[1];
541 uiverts
[2] = color
->ui
[2];
542 uiverts
[3] = color
->ui
[3];
545 for (i
= 0; i
< 4; i
++) {
546 ctx
->vertices
[i
][1][0] = 0;
547 ctx
->vertices
[i
][1][1] = 0;
548 ctx
->vertices
[i
][1][2] = 0;
549 ctx
->vertices
[i
][1][3] = 0;
554 static void get_texcoords(struct pipe_sampler_view
*src
,
555 unsigned src_width0
, unsigned src_height0
,
556 unsigned x1
, unsigned y1
,
557 unsigned x2
, unsigned y2
,
560 struct pipe_resource
*tex
= src
->texture
;
561 unsigned level
= src
->u
.tex
.first_level
;
562 boolean normalized
= tex
->target
!= PIPE_TEXTURE_RECT
;
565 out
[0] = x1
/ (float)u_minify(src_width0
, level
);
566 out
[1] = y1
/ (float)u_minify(src_height0
, level
);
567 out
[2] = x2
/ (float)u_minify(src_width0
, level
);
568 out
[3] = y2
/ (float)u_minify(src_height0
, level
);
577 static void set_texcoords_in_vertices(const float coord
[4],
578 float *out
, unsigned stride
)
580 out
[0] = coord
[0]; /*t0.s*/
581 out
[1] = coord
[1]; /*t0.t*/
583 out
[0] = coord
[2]; /*t1.s*/
584 out
[1] = coord
[1]; /*t1.t*/
586 out
[0] = coord
[2]; /*t2.s*/
587 out
[1] = coord
[3]; /*t2.t*/
589 out
[0] = coord
[0]; /*t3.s*/
590 out
[1] = coord
[3]; /*t3.t*/
593 static void blitter_set_texcoords(struct blitter_context_priv
*ctx
,
594 struct pipe_sampler_view
*src
,
595 unsigned src_width0
, unsigned src_height0
,
597 unsigned x1
, unsigned y1
,
598 unsigned x2
, unsigned y2
)
602 float face_coord
[4][2];
604 get_texcoords(src
, src_width0
, src_height0
, x1
, y1
, x2
, y2
, coord
);
606 if (src
->texture
->target
== PIPE_TEXTURE_CUBE
) {
607 set_texcoords_in_vertices(coord
, &face_coord
[0][0], 2);
608 util_map_texcoords2d_onto_cubemap(layer
,
609 /* pointer, stride in floats */
610 &face_coord
[0][0], 2,
611 &ctx
->vertices
[0][1][0], 8);
613 set_texcoords_in_vertices(coord
, &ctx
->vertices
[0][1][0], 8);
617 switch (src
->texture
->target
) {
618 case PIPE_TEXTURE_3D
:
620 float r
= layer
/ (float)u_minify(src
->texture
->depth0
,
621 src
->u
.tex
.first_level
);
622 for (i
= 0; i
< 4; i
++)
623 ctx
->vertices
[i
][1][2] = r
; /*r*/
627 case PIPE_TEXTURE_1D_ARRAY
:
628 for (i
= 0; i
< 4; i
++)
629 ctx
->vertices
[i
][1][1] = layer
; /*t*/
632 case PIPE_TEXTURE_2D_ARRAY
:
633 for (i
= 0; i
< 4; i
++)
634 ctx
->vertices
[i
][1][2] = layer
; /*r*/
641 static void blitter_set_dst_dimensions(struct blitter_context_priv
*ctx
,
642 unsigned width
, unsigned height
)
644 ctx
->dst_width
= width
;
645 ctx
->dst_height
= height
;
649 void *blitter_get_fs_col(struct blitter_context_priv
*ctx
, unsigned num_cbufs
,
652 struct pipe_context
*pipe
= ctx
->base
.pipe
;
654 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
657 if (!ctx
->fs_col_int
[num_cbufs
])
658 ctx
->fs_col_int
[num_cbufs
] =
659 util_make_fragment_cloneinput_shader(pipe
, num_cbufs
,
660 TGSI_SEMANTIC_GENERIC
,
661 TGSI_INTERPOLATE_CONSTANT
);
662 return ctx
->fs_col_int
[num_cbufs
];
664 if (!ctx
->fs_col
[num_cbufs
])
665 ctx
->fs_col
[num_cbufs
] =
666 util_make_fragment_cloneinput_shader(pipe
, num_cbufs
,
667 TGSI_SEMANTIC_GENERIC
,
668 TGSI_INTERPOLATE_LINEAR
);
669 return ctx
->fs_col
[num_cbufs
];
674 void *blitter_get_fs_texfetch_col(struct blitter_context_priv
*ctx
,
677 struct pipe_context
*pipe
= ctx
->base
.pipe
;
679 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
681 /* Create the fragment shader on-demand. */
682 if (!ctx
->fs_texfetch_col
[tex_target
]) {
683 unsigned tgsi_tex
= util_pipe_tex_to_tgsi_tex(tex_target
);
685 ctx
->fs_texfetch_col
[tex_target
] =
686 util_make_fragment_tex_shader(pipe
, tgsi_tex
, TGSI_INTERPOLATE_LINEAR
);
689 return ctx
->fs_texfetch_col
[tex_target
];
693 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv
*ctx
,
696 struct pipe_context
*pipe
= ctx
->base
.pipe
;
698 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
700 /* Create the fragment shader on-demand. */
701 if (!ctx
->fs_texfetch_depth
[tex_target
]) {
702 unsigned tgsi_tex
= util_pipe_tex_to_tgsi_tex(tex_target
);
704 ctx
->fs_texfetch_depth
[tex_target
] =
705 util_make_fragment_tex_shader_writedepth(pipe
, tgsi_tex
,
706 TGSI_INTERPOLATE_LINEAR
);
709 return ctx
->fs_texfetch_depth
[tex_target
];
713 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv
*ctx
,
716 struct pipe_context
*pipe
= ctx
->base
.pipe
;
718 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
720 /* Create the fragment shader on-demand. */
721 if (!ctx
->fs_texfetch_depthstencil
[tex_target
]) {
722 unsigned tgsi_tex
= util_pipe_tex_to_tgsi_tex(tex_target
);
724 ctx
->fs_texfetch_depthstencil
[tex_target
] =
725 util_make_fragment_tex_shader_writedepthstencil(pipe
, tgsi_tex
,
726 TGSI_INTERPOLATE_LINEAR
);
729 return ctx
->fs_texfetch_depthstencil
[tex_target
];
733 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv
*ctx
,
736 struct pipe_context
*pipe
= ctx
->base
.pipe
;
738 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
740 /* Create the fragment shader on-demand. */
741 if (!ctx
->fs_texfetch_stencil
[tex_target
]) {
742 unsigned tgsi_tex
= util_pipe_tex_to_tgsi_tex(tex_target
);
744 ctx
->fs_texfetch_stencil
[tex_target
] =
745 util_make_fragment_tex_shader_writestencil(pipe
, tgsi_tex
,
746 TGSI_INTERPOLATE_LINEAR
);
749 return ctx
->fs_texfetch_stencil
[tex_target
];
752 static void blitter_set_common_draw_rect_state(struct blitter_context_priv
*ctx
)
754 struct pipe_context
*pipe
= ctx
->base
.pipe
;
756 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
757 pipe
->bind_vs_state(pipe
, ctx
->vs
);
758 if (ctx
->has_geometry_shader
)
759 pipe
->bind_gs_state(pipe
, NULL
);
760 if (ctx
->has_stream_out
)
761 pipe
->set_stream_output_targets(pipe
, 0, NULL
, 0);
764 static void blitter_draw(struct blitter_context_priv
*ctx
,
765 unsigned x1
, unsigned y1
,
766 unsigned x2
, unsigned y2
,
769 struct pipe_resource
*buf
= NULL
;
772 blitter_set_rectangle(ctx
, x1
, y1
, x2
, y2
, depth
);
774 u_upload_data(ctx
->upload
, 0, sizeof(ctx
->vertices
), ctx
->vertices
,
776 u_upload_unmap(ctx
->upload
);
777 util_draw_vertex_buffer(ctx
->base
.pipe
, NULL
, buf
, offset
,
778 PIPE_PRIM_TRIANGLE_FAN
, 4, 2);
779 pipe_resource_reference(&buf
, NULL
);
782 static void blitter_draw_rectangle(struct blitter_context
*blitter
,
783 unsigned x1
, unsigned y1
,
784 unsigned x2
, unsigned y2
,
786 enum blitter_attrib_type type
,
787 const union pipe_color_union
*attrib
)
789 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
792 case UTIL_BLITTER_ATTRIB_COLOR
:
793 blitter_set_clear_color(ctx
, attrib
);
796 case UTIL_BLITTER_ATTRIB_TEXCOORD
:
797 set_texcoords_in_vertices(attrib
->f
, &ctx
->vertices
[0][1][0], 8);
803 blitter_draw(ctx
, x1
, y1
, x2
, y2
, depth
);
806 static void util_blitter_clear_custom(struct blitter_context
*blitter
,
807 unsigned width
, unsigned height
,
809 unsigned clear_buffers
,
810 enum pipe_format cbuf_format
,
811 const union pipe_color_union
*color
,
812 double depth
, unsigned stencil
,
813 void *custom_blend
, void *custom_dsa
)
815 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
816 struct pipe_context
*pipe
= ctx
->base
.pipe
;
817 struct pipe_stencil_ref sr
= { { 0 } };
818 boolean int_format
= util_format_is_pure_integer(cbuf_format
);
819 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
821 blitter_set_running_flag(ctx
);
822 blitter_check_saved_vertex_states(ctx
);
823 blitter_check_saved_fragment_states(ctx
);
827 pipe
->bind_blend_state(pipe
, custom_blend
);
828 } else if (clear_buffers
& PIPE_CLEAR_COLOR
) {
829 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
831 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
835 pipe
->bind_depth_stencil_alpha_state(pipe
, custom_dsa
);
836 } else if ((clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
837 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
838 } else if (clear_buffers
& PIPE_CLEAR_DEPTH
) {
839 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
840 } else if (clear_buffers
& PIPE_CLEAR_STENCIL
) {
841 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
843 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
846 sr
.ref_value
[0] = stencil
& 0xff;
847 pipe
->set_stencil_ref(pipe
, &sr
);
849 if (util_format_is_pure_sint(cbuf_format
)) {
850 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_sint_state
);
851 } else if (util_format_is_pure_uint(cbuf_format
)) {
852 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_uint_state
);
854 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
856 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, num_cbufs
, int_format
));
857 pipe
->set_sample_mask(pipe
, ~0);
859 blitter_set_common_draw_rect_state(ctx
);
860 blitter_set_dst_dimensions(ctx
, width
, height
);
861 blitter
->draw_rectangle(blitter
, 0, 0, width
, height
, depth
,
862 UTIL_BLITTER_ATTRIB_COLOR
, color
);
864 blitter_restore_vertex_states(ctx
);
865 blitter_restore_fragment_states(ctx
);
866 blitter_unset_running_flag(ctx
);
869 void util_blitter_clear(struct blitter_context
*blitter
,
870 unsigned width
, unsigned height
,
872 unsigned clear_buffers
,
873 enum pipe_format cbuf_format
,
874 const union pipe_color_union
*color
,
875 double depth
, unsigned stencil
)
877 util_blitter_clear_custom(blitter
, width
, height
, num_cbufs
,
878 clear_buffers
, cbuf_format
, color
, depth
, stencil
,
882 void util_blitter_clear_depth_custom(struct blitter_context
*blitter
,
883 unsigned width
, unsigned height
,
884 double depth
, void *custom_dsa
)
886 static const union pipe_color_union color
;
887 util_blitter_clear_custom(blitter
, width
, height
, 0,
888 0, PIPE_FORMAT_NONE
, &color
, depth
, 0, NULL
, custom_dsa
);
892 boolean
is_overlap(unsigned sx1
, unsigned sx2
, unsigned sy1
, unsigned sy2
,
893 unsigned dx1
, unsigned dx2
, unsigned dy1
, unsigned dy2
)
895 return sx1
< dx2
&& sx2
> dx1
&& sy1
< dy2
&& sy2
> dy1
;
898 void util_blitter_default_dst_texture(struct pipe_surface
*dst_templ
,
899 struct pipe_resource
*dst
,
902 const struct pipe_box
*srcbox
)
904 memset(dst_templ
, 0, sizeof(*dst_templ
));
905 dst_templ
->format
= dst
->format
;
906 if (util_format_is_depth_or_stencil(dst
->format
)) {
907 dst_templ
->usage
= PIPE_BIND_DEPTH_STENCIL
;
909 dst_templ
->usage
= PIPE_BIND_RENDER_TARGET
;
911 dst_templ
->format
= util_format_linear(dst
->format
);
912 dst_templ
->u
.tex
.level
= dstlevel
;
913 dst_templ
->u
.tex
.first_layer
= dstz
;
914 dst_templ
->u
.tex
.last_layer
= dstz
+ srcbox
->depth
- 1;
917 void util_blitter_default_src_texture(struct pipe_sampler_view
*src_templ
,
918 struct pipe_resource
*src
,
921 memset(src_templ
, 0, sizeof(*src_templ
));
922 src_templ
->format
= util_format_linear(src
->format
);
923 src_templ
->u
.tex
.first_level
= srclevel
;
924 src_templ
->u
.tex
.last_level
= srclevel
;
925 src_templ
->u
.tex
.first_layer
= 0;
926 src_templ
->u
.tex
.last_layer
=
927 src
->target
== PIPE_TEXTURE_3D
? u_minify(src
->depth0
, srclevel
) - 1
928 : src
->array_size
- 1;
929 src_templ
->swizzle_r
= PIPE_SWIZZLE_RED
;
930 src_templ
->swizzle_g
= PIPE_SWIZZLE_GREEN
;
931 src_templ
->swizzle_b
= PIPE_SWIZZLE_BLUE
;
932 src_templ
->swizzle_a
= PIPE_SWIZZLE_ALPHA
;
935 boolean
util_blitter_is_copy_supported(struct blitter_context
*blitter
,
936 const struct pipe_resource
*dst
,
937 const struct pipe_resource
*src
,
940 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
941 struct pipe_screen
*screen
= ctx
->base
.pipe
->screen
;
946 const struct util_format_description
*desc
=
947 util_format_description(dst
->format
);
949 is_stencil
= util_format_has_stencil(desc
);
951 /* Stencil export must be supported for stencil copy. */
952 if ((mask
& PIPE_MASK_S
) && is_stencil
&& !ctx
->has_stencil_export
) {
956 if (is_stencil
|| util_format_has_depth(desc
))
957 bind
= PIPE_BIND_DEPTH_STENCIL
;
959 bind
= PIPE_BIND_RENDER_TARGET
;
961 if (!screen
->is_format_supported(screen
, dst
->format
, dst
->target
,
962 dst
->nr_samples
, bind
)) {
968 if (!screen
->is_format_supported(screen
, src
->format
, src
->target
,
969 src
->nr_samples
, PIPE_BIND_SAMPLER_VIEW
)) {
973 /* Check stencil sampler support for stencil copy. */
974 if (util_format_has_stencil(util_format_description(src
->format
))) {
975 enum pipe_format stencil_format
=
976 util_format_stencil_only(src
->format
);
977 assert(stencil_format
!= PIPE_FORMAT_NONE
);
979 if (stencil_format
!= src
->format
&&
980 !screen
->is_format_supported(screen
, stencil_format
, src
->target
,
981 src
->nr_samples
, PIPE_BIND_SAMPLER_VIEW
)) {
990 void util_blitter_copy_texture(struct blitter_context
*blitter
,
991 struct pipe_resource
*dst
,
993 unsigned dstx
, unsigned dsty
, unsigned dstz
,
994 struct pipe_resource
*src
,
996 const struct pipe_box
*srcbox
)
998 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
999 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1000 struct pipe_surface
*dst_view
, dst_templ
;
1001 struct pipe_sampler_view src_templ
, *src_view
;
1004 assert(src
->target
< PIPE_MAX_TEXTURE_TYPES
);
1006 /* Initialize the surface. */
1007 util_blitter_default_dst_texture(&dst_templ
, dst
, dst_level
, dstz
, srcbox
);
1008 dst_view
= pipe
->create_surface(pipe
, dst
, &dst_templ
);
1010 /* Initialize the sampler view. */
1011 util_blitter_default_src_texture(&src_templ
, src
, src_level
);
1012 src_view
= pipe
->create_sampler_view(pipe
, src
, &src_templ
);
1015 util_blitter_copy_texture_view(blitter
, dst_view
, dstx
, dsty
, src_view
,
1016 srcbox
, src
->width0
, src
->height0
,
1019 pipe_surface_reference(&dst_view
, NULL
);
1020 pipe_sampler_view_reference(&src_view
, NULL
);
1023 void util_blitter_copy_texture_view(struct blitter_context
*blitter
,
1024 struct pipe_surface
*dst
,
1025 unsigned dstx
, unsigned dsty
,
1026 struct pipe_sampler_view
*src
,
1027 const struct pipe_box
*srcbox
,
1028 unsigned src_width0
, unsigned src_height0
,
1031 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1032 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1033 struct pipe_framebuffer_state fb_state
;
1034 enum pipe_texture_target src_target
= src
->texture
->target
;
1035 unsigned width
= srcbox
->width
;
1036 unsigned height
= srcbox
->height
;
1037 boolean blit_stencil
, blit_depth
;
1038 const struct util_format_description
*src_desc
=
1039 util_format_description(src
->format
);
1041 blit_depth
= util_format_has_depth(src_desc
) && (mask
& PIPE_MASK_Z
);
1042 blit_stencil
= util_format_has_stencil(src_desc
) && (mask
& PIPE_MASK_S
);
1044 /* If you want a fallback for stencil copies,
1045 * use util_blitter_copy_texture. */
1046 if (blit_stencil
&& !ctx
->has_stencil_export
) {
1047 blit_stencil
= FALSE
;
1053 /* Sanity checks. */
1054 if (dst
->texture
== src
->texture
&&
1055 dst
->u
.tex
.level
== src
->u
.tex
.first_level
) {
1056 assert(!is_overlap(srcbox
->x
, srcbox
->x
+ width
, srcbox
->y
, srcbox
->y
+ height
,
1057 dstx
, dstx
+ width
, dsty
, dsty
+ height
));
1059 /* XXX should handle 3d regions */
1060 assert(srcbox
->depth
== 1);
1062 /* Check whether the states are properly saved. */
1063 blitter_set_running_flag(ctx
);
1064 blitter_check_saved_vertex_states(ctx
);
1065 blitter_check_saved_fragment_states(ctx
);
1066 blitter_check_saved_textures(ctx
);
1067 blitter_check_saved_fb_state(ctx
);
1069 /* Initialize framebuffer state. */
1070 fb_state
.width
= dst
->width
;
1071 fb_state
.height
= dst
->height
;
1073 if (blit_depth
|| blit_stencil
) {
1074 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
1076 if (blit_depth
&& blit_stencil
) {
1077 pipe
->bind_depth_stencil_alpha_state(pipe
,
1078 ctx
->dsa_write_depth_stencil
);
1079 pipe
->bind_fs_state(pipe
,
1080 blitter_get_fs_texfetch_depthstencil(ctx
, src_target
));
1081 } else if (blit_depth
) {
1082 pipe
->bind_depth_stencil_alpha_state(pipe
,
1083 ctx
->dsa_write_depth_keep_stencil
);
1084 pipe
->bind_fs_state(pipe
,
1085 blitter_get_fs_texfetch_depth(ctx
, src_target
));
1086 } else { /* is_stencil */
1087 pipe
->bind_depth_stencil_alpha_state(pipe
,
1088 ctx
->dsa_keep_depth_write_stencil
);
1089 pipe
->bind_fs_state(pipe
,
1090 blitter_get_fs_texfetch_stencil(ctx
, src_target
));
1093 fb_state
.nr_cbufs
= 0;
1094 fb_state
.zsbuf
= dst
;
1096 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
1097 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
1098 pipe
->bind_fs_state(pipe
,
1099 blitter_get_fs_texfetch_col(ctx
, src_target
));
1101 fb_state
.nr_cbufs
= 1;
1102 fb_state
.cbufs
[0] = dst
;
1106 if (blit_depth
&& blit_stencil
) {
1107 /* Setup two samplers, one for depth and the other one for stencil. */
1108 struct pipe_sampler_view templ
;
1109 struct pipe_sampler_view
*views
[2];
1110 void *samplers
[2] = {ctx
->sampler_state
, ctx
->sampler_state
};
1113 templ
.format
= util_format_stencil_only(templ
.format
);
1114 assert(templ
.format
!= PIPE_FORMAT_NONE
);
1117 views
[1] = pipe
->create_sampler_view(pipe
, src
->texture
, &templ
);
1119 pipe
->set_fragment_sampler_views(pipe
, 2, views
);
1120 pipe
->bind_fragment_sampler_states(pipe
, 2, samplers
);
1122 pipe_sampler_view_reference(&views
[1], NULL
);
1124 pipe
->set_fragment_sampler_views(pipe
, 1, &src
);
1125 pipe
->bind_fragment_sampler_states(pipe
, 1, &ctx
->sampler_state
);
1128 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1129 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1130 pipe
->set_sample_mask(pipe
, ~0);
1132 blitter_set_common_draw_rect_state(ctx
);
1133 blitter_set_dst_dimensions(ctx
, dst
->width
, dst
->height
);
1135 switch (src_target
) {
1136 /* Draw the quad with the draw_rectangle callback. */
1137 case PIPE_TEXTURE_1D
:
1138 case PIPE_TEXTURE_2D
:
1139 case PIPE_TEXTURE_RECT
:
1141 /* Set texture coordinates. - use a pipe color union
1142 * for interface purposes.
1143 * XXX pipe_color_union is a wrong name since we use that to set
1144 * texture coordinates too.
1146 union pipe_color_union coord
;
1147 get_texcoords(src
, src_width0
, src_height0
, srcbox
->x
, srcbox
->y
,
1148 srcbox
->x
+width
, srcbox
->y
+height
, coord
.f
);
1151 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0,
1152 UTIL_BLITTER_ATTRIB_TEXCOORD
, &coord
);
1156 /* Draw the quad with the generic codepath. */
1158 /* Set texture coordinates. */
1159 switch (src_target
) {
1160 case PIPE_TEXTURE_1D_ARRAY
:
1161 case PIPE_TEXTURE_2D_ARRAY
:
1162 case PIPE_TEXTURE_3D
:
1163 case PIPE_TEXTURE_CUBE
:
1164 blitter_set_texcoords(ctx
, src
, src_width0
, src_height0
, srcbox
->z
,
1165 srcbox
->y
, srcbox
->x
,
1166 srcbox
->x
+ width
, srcbox
->y
+ height
);
1173 blitter_draw(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0);
1177 blitter_restore_vertex_states(ctx
);
1178 blitter_restore_fragment_states(ctx
);
1179 blitter_restore_textures(ctx
);
1180 blitter_restore_fb_state(ctx
);
1181 blitter_unset_running_flag(ctx
);
1184 /* Clear a region of a color surface to a constant value. */
1185 void util_blitter_clear_render_target(struct blitter_context
*blitter
,
1186 struct pipe_surface
*dstsurf
,
1187 const union pipe_color_union
*color
,
1188 unsigned dstx
, unsigned dsty
,
1189 unsigned width
, unsigned height
)
1191 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1192 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1193 struct pipe_framebuffer_state fb_state
;
1195 assert(dstsurf
->texture
);
1196 if (!dstsurf
->texture
)
1199 /* check the saved state */
1200 blitter_set_running_flag(ctx
);
1201 blitter_check_saved_vertex_states(ctx
);
1202 blitter_check_saved_fragment_states(ctx
);
1203 blitter_check_saved_fb_state(ctx
);
1206 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
1207 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
1208 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 1, FALSE
));
1209 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1211 /* set a framebuffer state */
1212 fb_state
.width
= dstsurf
->width
;
1213 fb_state
.height
= dstsurf
->height
;
1214 fb_state
.nr_cbufs
= 1;
1215 fb_state
.cbufs
[0] = dstsurf
;
1217 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1218 pipe
->set_sample_mask(pipe
, ~0);
1220 blitter_set_common_draw_rect_state(ctx
);
1221 blitter_set_dst_dimensions(ctx
, dstsurf
->width
, dstsurf
->height
);
1222 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, 0,
1223 UTIL_BLITTER_ATTRIB_COLOR
, color
);
1225 blitter_restore_vertex_states(ctx
);
1226 blitter_restore_fragment_states(ctx
);
1227 blitter_restore_fb_state(ctx
);
1228 blitter_unset_running_flag(ctx
);
1231 /* Clear a region of a depth stencil surface. */
1232 void util_blitter_clear_depth_stencil(struct blitter_context
*blitter
,
1233 struct pipe_surface
*dstsurf
,
1234 unsigned clear_flags
,
1237 unsigned dstx
, unsigned dsty
,
1238 unsigned width
, unsigned height
)
1240 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1241 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1242 struct pipe_framebuffer_state fb_state
;
1243 struct pipe_stencil_ref sr
= { { 0 } };
1245 assert(dstsurf
->texture
);
1246 if (!dstsurf
->texture
)
1249 /* check the saved state */
1250 blitter_set_running_flag(ctx
);
1251 blitter_check_saved_vertex_states(ctx
);
1252 blitter_check_saved_fragment_states(ctx
);
1253 blitter_check_saved_fb_state(ctx
);
1256 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
1257 if ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
1258 sr
.ref_value
[0] = stencil
& 0xff;
1259 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
1260 pipe
->set_stencil_ref(pipe
, &sr
);
1262 else if (clear_flags
& PIPE_CLEAR_DEPTH
) {
1263 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
1265 else if (clear_flags
& PIPE_CLEAR_STENCIL
) {
1266 sr
.ref_value
[0] = stencil
& 0xff;
1267 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
1268 pipe
->set_stencil_ref(pipe
, &sr
);
1271 /* hmm that should be illegal probably, or make it a no-op somewhere */
1272 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
1274 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 0, FALSE
));
1275 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1277 /* set a framebuffer state */
1278 fb_state
.width
= dstsurf
->width
;
1279 fb_state
.height
= dstsurf
->height
;
1280 fb_state
.nr_cbufs
= 0;
1281 fb_state
.cbufs
[0] = 0;
1282 fb_state
.zsbuf
= dstsurf
;
1283 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1284 pipe
->set_sample_mask(pipe
, ~0);
1286 blitter_set_common_draw_rect_state(ctx
);
1287 blitter_set_dst_dimensions(ctx
, dstsurf
->width
, dstsurf
->height
);
1288 blitter
->draw_rectangle(blitter
, dstx
, dsty
, dstx
+width
, dsty
+height
, depth
,
1289 UTIL_BLITTER_ATTRIB_NONE
, NULL
);
1291 blitter_restore_vertex_states(ctx
);
1292 blitter_restore_fragment_states(ctx
);
1293 blitter_restore_fb_state(ctx
);
1294 blitter_unset_running_flag(ctx
);
1297 /* draw a rectangle across a region using a custom dsa stage - for r600g */
1298 void util_blitter_custom_depth_stencil(struct blitter_context
*blitter
,
1299 struct pipe_surface
*zsurf
,
1300 struct pipe_surface
*cbsurf
,
1301 void *dsa_stage
, float depth
)
1303 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1304 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1305 struct pipe_framebuffer_state fb_state
;
1307 assert(zsurf
->texture
);
1308 if (!zsurf
->texture
)
1311 /* check the saved state */
1312 blitter_set_running_flag(ctx
);
1313 blitter_check_saved_vertex_states(ctx
);
1314 blitter_check_saved_fragment_states(ctx
);
1315 blitter_check_saved_fb_state(ctx
);
1318 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
1319 pipe
->bind_depth_stencil_alpha_state(pipe
, dsa_stage
);
1320 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 0, FALSE
));
1321 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
1323 /* set a framebuffer state */
1324 fb_state
.width
= zsurf
->width
;
1325 fb_state
.height
= zsurf
->height
;
1326 fb_state
.nr_cbufs
= 1;
1328 fb_state
.cbufs
[0] = cbsurf
;
1329 fb_state
.nr_cbufs
= 1;
1331 fb_state
.cbufs
[0] = NULL
;
1332 fb_state
.nr_cbufs
= 0;
1334 fb_state
.zsbuf
= zsurf
;
1335 pipe
->set_framebuffer_state(pipe
, &fb_state
);
1337 blitter_set_common_draw_rect_state(ctx
);
1338 blitter_set_dst_dimensions(ctx
, zsurf
->width
, zsurf
->height
);
1339 blitter
->draw_rectangle(blitter
, 0, 0, zsurf
->width
, zsurf
->height
, depth
,
1340 UTIL_BLITTER_ATTRIB_NONE
, NULL
);
1342 blitter_restore_vertex_states(ctx
);
1343 blitter_restore_fragment_states(ctx
);
1344 blitter_restore_fb_state(ctx
);
1345 blitter_unset_running_flag(ctx
);
1348 void util_blitter_copy_buffer(struct blitter_context
*blitter
,
1349 struct pipe_resource
*dst
,
1351 struct pipe_resource
*src
,
1355 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
1356 struct pipe_context
*pipe
= ctx
->base
.pipe
;
1357 struct pipe_vertex_buffer vb
;
1358 struct pipe_stream_output_target
*so_target
;
1360 if (srcx
>= src
->width0
||
1361 dstx
>= dst
->width0
) {
1364 if (srcx
+ size
> src
->width0
) {
1365 size
= src
->width0
- srcx
;
1367 if (dstx
+ size
> dst
->width0
) {
1368 size
= dst
->width0
- dstx
;
1371 /* Drivers not capable of Stream Out should not call this function
1372 * in the first place. */
1373 assert(ctx
->has_stream_out
);
1375 /* Some alignment is required. */
1376 if (srcx
% 4 != 0 || dstx
% 4 != 0 || size
% 4 != 0 ||
1377 !ctx
->has_stream_out
) {
1378 struct pipe_box box
;
1379 u_box_1d(srcx
, size
, &box
);
1380 util_resource_copy_region(pipe
, dst
, 0, dstx
, 0, 0, src
, 0, &box
);
1384 blitter_set_running_flag(ctx
);
1385 blitter_check_saved_vertex_states(ctx
);
1388 vb
.buffer_offset
= srcx
;
1391 pipe
->set_vertex_buffers(pipe
, 1, &vb
);
1392 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state_readbuf
);
1393 pipe
->bind_vs_state(pipe
, ctx
->vs_pos_only
);
1394 if (ctx
->has_geometry_shader
)
1395 pipe
->bind_gs_state(pipe
, NULL
);
1396 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_discard_state
);
1398 so_target
= pipe
->create_stream_output_target(pipe
, dst
, dstx
, size
);
1399 pipe
->set_stream_output_targets(pipe
, 1, &so_target
, 0);
1401 util_draw_arrays(pipe
, PIPE_PRIM_POINTS
, 0, size
/ 4);
1403 blitter_restore_vertex_states(ctx
);
1404 blitter_unset_running_flag(ctx
);
1405 pipe_so_target_reference(&so_target
, NULL
);