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, clear_depth_stencil
30 * 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_pack_color.h"
47 #include "util/u_sampler.h"
48 #include "util/u_simple_shaders.h"
49 #include "util/u_surface.h"
50 #include "util/u_texture.h"
52 #define INVALID_PTR ((void*)~0)
54 struct blitter_context_priv
56 struct blitter_context blitter
;
58 struct pipe_context
*pipe
; /**< pipe context */
59 struct pipe_resource
*vbuf
; /**< quad */
61 float vertices
[4][2][4]; /**< {pos, color} or {pos, texcoord} */
63 /* Templates for various state objects. */
64 struct pipe_sampler_state template_sampler_state
;
66 /* Constant state objects. */
68 void *vs_col
; /**< Vertex shader which passes {pos, color} to the output */
69 void *vs_tex
; /**< Vertex shader which passes {pos, texcoord} to the output.*/
71 /* Fragment shaders. */
72 /* The shader at index i outputs color to color buffers 0,1,...,i-1. */
73 void *fs_col
[PIPE_MAX_COLOR_BUFS
+1];
75 /* FS which outputs a color from a texture,
76 where the index is PIPE_TEXTURE_* to be sampled. */
77 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
79 /* FS which outputs a depth from a texture,
80 where the index is PIPE_TEXTURE_* to be sampled. */
81 void *fs_texfetch_depth
[PIPE_MAX_TEXTURE_TYPES
];
84 void *blend_write_color
; /**< blend state with writemask of RGBA */
85 void *blend_keep_color
; /**< blend state with writemask of 0 */
87 /* Depth stencil alpha state. */
88 void *dsa_write_depth_stencil
;
89 void *dsa_write_depth_keep_stencil
;
90 void *dsa_keep_depth_stencil
;
91 void *dsa_keep_depth_write_stencil
;
95 /* Sampler state for clamping to a miplevel. */
96 void *sampler_state
[PIPE_MAX_TEXTURE_LEVELS
];
98 /* Rasterizer state. */
101 struct pipe_sampler_view
*sampler_view
;
103 /* Viewport state. */
104 struct pipe_viewport_state viewport
;
107 struct pipe_clip_state clip
;
110 struct blitter_context
*util_blitter_create(struct pipe_context
*pipe
)
112 struct blitter_context_priv
*ctx
;
113 struct pipe_blend_state blend
;
114 struct pipe_depth_stencil_alpha_state dsa
;
115 struct pipe_rasterizer_state rs_state
;
116 struct pipe_sampler_state
*sampler_state
;
117 struct pipe_vertex_element velem
[2];
120 ctx
= CALLOC_STRUCT(blitter_context_priv
);
126 /* init state objects for them to be considered invalid */
127 ctx
->blitter
.saved_blend_state
= INVALID_PTR
;
128 ctx
->blitter
.saved_dsa_state
= INVALID_PTR
;
129 ctx
->blitter
.saved_rs_state
= INVALID_PTR
;
130 ctx
->blitter
.saved_fs
= INVALID_PTR
;
131 ctx
->blitter
.saved_vs
= INVALID_PTR
;
132 ctx
->blitter
.saved_velem_state
= INVALID_PTR
;
133 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
134 ctx
->blitter
.saved_num_sampler_views
= ~0;
135 ctx
->blitter
.saved_num_sampler_states
= ~0;
136 ctx
->blitter
.saved_num_vertex_buffers
= ~0;
138 /* blend state objects */
139 memset(&blend
, 0, sizeof(blend
));
140 ctx
->blend_keep_color
= pipe
->create_blend_state(pipe
, &blend
);
142 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
143 ctx
->blend_write_color
= pipe
->create_blend_state(pipe
, &blend
);
145 /* depth stencil alpha state objects */
146 memset(&dsa
, 0, sizeof(dsa
));
147 ctx
->dsa_keep_depth_stencil
=
148 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
150 dsa
.depth
.enabled
= 1;
151 dsa
.depth
.writemask
= 1;
152 dsa
.depth
.func
= PIPE_FUNC_ALWAYS
;
153 ctx
->dsa_write_depth_keep_stencil
=
154 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
156 dsa
.stencil
[0].enabled
= 1;
157 dsa
.stencil
[0].func
= PIPE_FUNC_ALWAYS
;
158 dsa
.stencil
[0].fail_op
= PIPE_STENCIL_OP_REPLACE
;
159 dsa
.stencil
[0].zpass_op
= PIPE_STENCIL_OP_REPLACE
;
160 dsa
.stencil
[0].zfail_op
= PIPE_STENCIL_OP_REPLACE
;
161 dsa
.stencil
[0].valuemask
= 0xff;
162 dsa
.stencil
[0].writemask
= 0xff;
163 ctx
->dsa_write_depth_stencil
=
164 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
167 dsa
.depth
.enabled
= 0;
168 dsa
.depth
.writemask
= 0;
169 ctx
->dsa_keep_depth_write_stencil
=
170 pipe
->create_depth_stencil_alpha_state(pipe
, &dsa
);
173 sampler_state
= &ctx
->template_sampler_state
;
174 sampler_state
->wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
175 sampler_state
->wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
176 sampler_state
->wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
177 sampler_state
->normalized_coords
= TRUE
;
178 /* The sampler state objects which sample from a specified mipmap level
179 * are created on-demand. */
181 /* rasterizer state */
182 memset(&rs_state
, 0, sizeof(rs_state
));
183 rs_state
.cull_face
= PIPE_FACE_NONE
;
184 rs_state
.gl_rasterization_rules
= 1;
185 rs_state
.flatshade
= 1;
186 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
188 /* vertex elements state */
189 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
190 for (i
= 0; i
< 2; i
++) {
191 velem
[i
].src_offset
= i
* 4 * sizeof(float);
192 velem
[i
].instance_divisor
= 0;
193 velem
[i
].vertex_buffer_index
= 0;
194 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
196 ctx
->velem_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
198 /* fragment shaders are created on-demand */
202 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
203 TGSI_SEMANTIC_COLOR
};
204 const uint semantic_indices
[] = { 0, 0 };
206 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
210 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
211 TGSI_SEMANTIC_GENERIC
};
212 const uint semantic_indices
[] = { 0, 0 };
214 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
218 /* set invariant vertex coordinates */
219 for (i
= 0; i
< 4; i
++)
220 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
222 /* create the vertex buffer */
223 ctx
->vbuf
= pipe_buffer_create(ctx
->pipe
->screen
,
224 PIPE_BIND_VERTEX_BUFFER
,
225 sizeof(ctx
->vertices
));
227 return &ctx
->blitter
;
230 void util_blitter_destroy(struct blitter_context
*blitter
)
232 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
233 struct pipe_context
*pipe
= ctx
->pipe
;
236 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
237 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
238 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
239 pipe
->delete_depth_stencil_alpha_state(pipe
,
240 ctx
->dsa_write_depth_keep_stencil
);
241 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
242 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
244 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
245 pipe
->delete_vs_state(pipe
, ctx
->vs_col
);
246 pipe
->delete_vs_state(pipe
, ctx
->vs_tex
);
247 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state
);
249 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
250 if (ctx
->fs_texfetch_col
[i
])
251 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
252 if (ctx
->fs_texfetch_depth
[i
])
253 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
256 for (i
= 0; i
<= PIPE_MAX_COLOR_BUFS
&& ctx
->fs_col
[i
]; i
++)
258 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
260 for (i
= 0; i
< PIPE_MAX_TEXTURE_LEVELS
; i
++)
261 if (ctx
->sampler_state
[i
])
262 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
[i
]);
264 if (ctx
->sampler_view
) {
265 pipe_sampler_view_reference(&ctx
->sampler_view
, NULL
);
268 pipe_resource_reference(&ctx
->vbuf
, NULL
);
272 static void blitter_check_saved_CSOs(struct blitter_context_priv
*ctx
)
274 /* make sure these CSOs have been saved */
275 assert(ctx
->blitter
.saved_blend_state
!= INVALID_PTR
&&
276 ctx
->blitter
.saved_dsa_state
!= INVALID_PTR
&&
277 ctx
->blitter
.saved_rs_state
!= INVALID_PTR
&&
278 ctx
->blitter
.saved_fs
!= INVALID_PTR
&&
279 ctx
->blitter
.saved_vs
!= INVALID_PTR
&&
280 ctx
->blitter
.saved_velem_state
!= INVALID_PTR
);
283 static void blitter_restore_CSOs(struct blitter_context_priv
*ctx
)
285 struct pipe_context
*pipe
= ctx
->pipe
;
287 /* restore the state objects which are always required to be saved */
288 pipe
->bind_blend_state(pipe
, ctx
->blitter
.saved_blend_state
);
289 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->blitter
.saved_dsa_state
);
290 pipe
->bind_rasterizer_state(pipe
, ctx
->blitter
.saved_rs_state
);
291 pipe
->bind_fs_state(pipe
, ctx
->blitter
.saved_fs
);
292 pipe
->bind_vs_state(pipe
, ctx
->blitter
.saved_vs
);
293 pipe
->bind_vertex_elements_state(pipe
, ctx
->blitter
.saved_velem_state
);
295 ctx
->blitter
.saved_blend_state
= INVALID_PTR
;
296 ctx
->blitter
.saved_dsa_state
= INVALID_PTR
;
297 ctx
->blitter
.saved_rs_state
= INVALID_PTR
;
298 ctx
->blitter
.saved_fs
= INVALID_PTR
;
299 ctx
->blitter
.saved_vs
= INVALID_PTR
;
300 ctx
->blitter
.saved_velem_state
= INVALID_PTR
;
302 pipe
->set_stencil_ref(pipe
, &ctx
->blitter
.saved_stencil_ref
);
304 pipe
->set_viewport_state(pipe
, &ctx
->blitter
.saved_viewport
);
305 pipe
->set_clip_state(pipe
, &ctx
->blitter
.saved_clip
);
307 /* restore the state objects which are required to be saved before copy/fill
309 if (ctx
->blitter
.saved_fb_state
.nr_cbufs
!= ~0) {
310 pipe
->set_framebuffer_state(pipe
, &ctx
->blitter
.saved_fb_state
);
311 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
314 if (ctx
->blitter
.saved_num_sampler_states
!= ~0) {
315 pipe
->bind_fragment_sampler_states(pipe
,
316 ctx
->blitter
.saved_num_sampler_states
,
317 ctx
->blitter
.saved_sampler_states
);
318 ctx
->blitter
.saved_num_sampler_states
= ~0;
321 if (ctx
->blitter
.saved_num_sampler_views
!= ~0) {
322 pipe
->set_fragment_sampler_views(pipe
,
323 ctx
->blitter
.saved_num_sampler_views
,
324 ctx
->blitter
.saved_sampler_views
);
325 ctx
->blitter
.saved_num_sampler_views
= ~0;
328 if (ctx
->blitter
.saved_num_vertex_buffers
!= ~0) {
329 pipe
->set_vertex_buffers(pipe
,
330 ctx
->blitter
.saved_num_vertex_buffers
,
331 ctx
->blitter
.saved_vertex_buffers
);
332 ctx
->blitter
.saved_num_vertex_buffers
= ~0;
336 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
337 unsigned x1
, unsigned y1
,
338 unsigned x2
, unsigned y2
,
339 unsigned width
, unsigned height
,
344 /* set vertex positions */
345 ctx
->vertices
[0][0][0] = (float)x1
/ width
* 2.0f
- 1.0f
; /*v0.x*/
346 ctx
->vertices
[0][0][1] = (float)y1
/ height
* 2.0f
- 1.0f
; /*v0.y*/
348 ctx
->vertices
[1][0][0] = (float)x2
/ width
* 2.0f
- 1.0f
; /*v1.x*/
349 ctx
->vertices
[1][0][1] = (float)y1
/ height
* 2.0f
- 1.0f
; /*v1.y*/
351 ctx
->vertices
[2][0][0] = (float)x2
/ width
* 2.0f
- 1.0f
; /*v2.x*/
352 ctx
->vertices
[2][0][1] = (float)y2
/ height
* 2.0f
- 1.0f
; /*v2.y*/
354 ctx
->vertices
[3][0][0] = (float)x1
/ width
* 2.0f
- 1.0f
; /*v3.x*/
355 ctx
->vertices
[3][0][1] = (float)y2
/ height
* 2.0f
- 1.0f
; /*v3.y*/
357 for (i
= 0; i
< 4; i
++)
358 ctx
->vertices
[i
][0][2] = depth
; /*z*/
361 ctx
->viewport
.scale
[0] = 0.5f
* width
;
362 ctx
->viewport
.scale
[1] = 0.5f
* height
;
363 ctx
->viewport
.scale
[2] = 1.0f
;
364 ctx
->viewport
.scale
[3] = 1.0f
;
365 ctx
->viewport
.translate
[0] = 0.5f
* width
;
366 ctx
->viewport
.translate
[1] = 0.5f
* height
;
367 ctx
->viewport
.translate
[2] = 0.0f
;
368 ctx
->viewport
.translate
[3] = 0.0f
;
369 ctx
->pipe
->set_viewport_state(ctx
->pipe
, &ctx
->viewport
);
372 ctx
->pipe
->set_clip_state(ctx
->pipe
, &ctx
->clip
);
375 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
381 for (i
= 0; i
< 4; i
++) {
382 ctx
->vertices
[i
][1][0] = rgba
[0];
383 ctx
->vertices
[i
][1][1] = rgba
[1];
384 ctx
->vertices
[i
][1][2] = rgba
[2];
385 ctx
->vertices
[i
][1][3] = rgba
[3];
388 for (i
= 0; i
< 4; i
++) {
389 ctx
->vertices
[i
][1][0] = 0;
390 ctx
->vertices
[i
][1][1] = 0;
391 ctx
->vertices
[i
][1][2] = 0;
392 ctx
->vertices
[i
][1][3] = 0;
397 static void blitter_set_texcoords_2d(struct blitter_context_priv
*ctx
,
398 struct pipe_resource
*src
,
399 struct pipe_subresource subsrc
,
400 unsigned x1
, unsigned y1
,
401 unsigned x2
, unsigned y2
)
404 float s1
= x1
/ (float)u_minify(src
->width0
, subsrc
.level
);
405 float t1
= y1
/ (float)u_minify(src
->height0
, subsrc
.level
);
406 float s2
= x2
/ (float)u_minify(src
->width0
, subsrc
.level
);
407 float t2
= y2
/ (float)u_minify(src
->height0
, subsrc
.level
);
409 ctx
->vertices
[0][1][0] = s1
; /*t0.s*/
410 ctx
->vertices
[0][1][1] = t1
; /*t0.t*/
412 ctx
->vertices
[1][1][0] = s2
; /*t1.s*/
413 ctx
->vertices
[1][1][1] = t1
; /*t1.t*/
415 ctx
->vertices
[2][1][0] = s2
; /*t2.s*/
416 ctx
->vertices
[2][1][1] = t2
; /*t2.t*/
418 ctx
->vertices
[3][1][0] = s1
; /*t3.s*/
419 ctx
->vertices
[3][1][1] = t2
; /*t3.t*/
421 for (i
= 0; i
< 4; i
++) {
422 ctx
->vertices
[i
][1][2] = 0; /*r*/
423 ctx
->vertices
[i
][1][3] = 1; /*q*/
427 static void blitter_set_texcoords_3d(struct blitter_context_priv
*ctx
,
428 struct pipe_resource
*src
,
429 struct pipe_subresource subsrc
,
431 unsigned x1
, unsigned y1
,
432 unsigned x2
, unsigned y2
)
435 float r
= zslice
/ (float)u_minify(src
->depth0
, subsrc
.level
);
437 blitter_set_texcoords_2d(ctx
, src
, subsrc
, x1
, y1
, x2
, y2
);
439 for (i
= 0; i
< 4; i
++)
440 ctx
->vertices
[i
][1][2] = r
; /*r*/
443 static void blitter_set_texcoords_cube(struct blitter_context_priv
*ctx
,
444 struct pipe_resource
*src
,
445 struct pipe_subresource subsrc
,
446 unsigned x1
, unsigned y1
,
447 unsigned x2
, unsigned y2
)
450 float s1
= x1
/ (float)u_minify(src
->width0
, subsrc
.level
);
451 float t1
= y1
/ (float)u_minify(src
->height0
, subsrc
.level
);
452 float s2
= x2
/ (float)u_minify(src
->width0
, subsrc
.level
);
453 float t2
= y2
/ (float)u_minify(src
->height0
, subsrc
.level
);
465 util_map_texcoords2d_onto_cubemap(subsrc
.face
,
466 /* pointer, stride in floats */
468 &ctx
->vertices
[0][1][0], 8);
470 for (i
= 0; i
< 4; i
++)
471 ctx
->vertices
[i
][1][3] = 1; /*q*/
474 static void blitter_draw_quad(struct blitter_context_priv
*ctx
)
476 struct pipe_context
*pipe
= ctx
->pipe
;
478 /* write vertices and draw them */
479 pipe_buffer_write(pipe
, ctx
->vbuf
,
480 0, sizeof(ctx
->vertices
), ctx
->vertices
);
482 util_draw_vertex_buffer(pipe
, ctx
->vbuf
, 0, PIPE_PRIM_TRIANGLE_FAN
,
484 2); /* attribs/vert */
488 void **blitter_get_sampler_state(struct blitter_context_priv
*ctx
,
491 struct pipe_context
*pipe
= ctx
->pipe
;
492 struct pipe_sampler_state
*sampler_state
= &ctx
->template_sampler_state
;
494 assert(miplevel
< PIPE_MAX_TEXTURE_LEVELS
);
496 /* Create the sampler state on-demand. */
497 if (!ctx
->sampler_state
[miplevel
]) {
498 sampler_state
->lod_bias
= miplevel
;
499 sampler_state
->min_lod
= miplevel
;
500 sampler_state
->max_lod
= miplevel
;
502 ctx
->sampler_state
[miplevel
] = pipe
->create_sampler_state(pipe
,
506 /* Return void** so that it can be passed to bind_fragment_sampler_states
508 return &ctx
->sampler_state
[miplevel
];
512 void *blitter_get_fs_col(struct blitter_context_priv
*ctx
, unsigned num_cbufs
)
514 struct pipe_context
*pipe
= ctx
->pipe
;
516 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
518 if (!ctx
->fs_col
[num_cbufs
])
519 ctx
->fs_col
[num_cbufs
] =
520 util_make_fragment_clonecolor_shader(pipe
, num_cbufs
);
522 return ctx
->fs_col
[num_cbufs
];
526 void *blitter_get_fs_texfetch_col(struct blitter_context_priv
*ctx
,
529 struct pipe_context
*pipe
= ctx
->pipe
;
531 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
533 /* Create the fragment shader on-demand. */
534 if (!ctx
->fs_texfetch_col
[tex_target
]) {
535 switch (tex_target
) {
536 case PIPE_TEXTURE_2D
:
537 ctx
->fs_texfetch_col
[PIPE_TEXTURE_2D
] =
538 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_2D
);
540 case PIPE_TEXTURE_3D
:
541 ctx
->fs_texfetch_col
[PIPE_TEXTURE_3D
] =
542 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_3D
);
544 case PIPE_TEXTURE_CUBE
:
545 ctx
->fs_texfetch_col
[PIPE_TEXTURE_CUBE
] =
546 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_CUBE
);
548 case PIPE_TEXTURE_1D
:
550 ctx
->fs_texfetch_col
[PIPE_TEXTURE_1D
] =
551 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_1D
);
552 tex_target
= PIPE_TEXTURE_1D
; /* for the default case */
556 return ctx
->fs_texfetch_col
[tex_target
];
560 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv
*ctx
,
563 struct pipe_context
*pipe
= ctx
->pipe
;
565 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
567 /* Create the fragment shader on-demand. */
568 if (!ctx
->fs_texfetch_depth
[tex_target
]) {
569 switch (tex_target
) {
570 case PIPE_TEXTURE_2D
:
571 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_2D
] =
572 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_2D
);
574 case PIPE_TEXTURE_3D
:
575 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_3D
] =
576 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_3D
);
578 case PIPE_TEXTURE_CUBE
:
579 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_CUBE
] =
580 util_make_fragment_tex_shader_writedepth(pipe
,TGSI_TEXTURE_CUBE
);
582 case PIPE_TEXTURE_1D
:
584 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_1D
] =
585 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_1D
);
586 tex_target
= PIPE_TEXTURE_1D
; /* for the default case */
590 return ctx
->fs_texfetch_depth
[tex_target
];
593 void util_blitter_clear(struct blitter_context
*blitter
,
594 unsigned width
, unsigned height
,
596 unsigned clear_buffers
,
598 double depth
, unsigned stencil
)
600 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
601 struct pipe_context
*pipe
= ctx
->pipe
;
602 struct pipe_stencil_ref sr
= { { 0 } };
604 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
606 blitter_check_saved_CSOs(ctx
);
609 if (clear_buffers
& PIPE_CLEAR_COLOR
)
610 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
612 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
614 if ((clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
615 sr
.ref_value
[0] = stencil
& 0xff;
616 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
617 pipe
->set_stencil_ref(pipe
, &sr
);
619 else if (clear_buffers
& PIPE_CLEAR_DEPTH
) {
620 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
622 else if (clear_buffers
& PIPE_CLEAR_STENCIL
) {
623 sr
.ref_value
[0] = stencil
& 0xff;
624 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
625 pipe
->set_stencil_ref(pipe
, &sr
);
628 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
630 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
631 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
632 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, num_cbufs
));
633 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
635 blitter_set_clear_color(ctx
, rgba
);
636 blitter_set_rectangle(ctx
, 0, 0, width
, height
, width
, height
, depth
);
637 blitter_draw_quad(ctx
);
638 blitter_restore_CSOs(ctx
);
642 boolean
is_overlap(unsigned sx1
, unsigned sx2
, unsigned sy1
, unsigned sy2
,
643 unsigned dx1
, unsigned dx2
, unsigned dy1
, unsigned dy2
)
645 return sx1
< dx2
&& sx2
> dx1
&& sy1
< dy2
&& sy2
> dy1
;
648 void util_blitter_copy_region(struct blitter_context
*blitter
,
649 struct pipe_resource
*dst
,
650 struct pipe_subresource subdst
,
651 unsigned dstx
, unsigned dsty
, unsigned dstz
,
652 struct pipe_resource
*src
,
653 struct pipe_subresource subsrc
,
654 unsigned srcx
, unsigned srcy
, unsigned srcz
,
655 unsigned width
, unsigned height
,
656 boolean ignore_stencil
)
658 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
659 struct pipe_context
*pipe
= ctx
->pipe
;
660 struct pipe_screen
*screen
= pipe
->screen
;
661 struct pipe_surface
*dstsurf
;
662 struct pipe_framebuffer_state fb_state
;
663 struct pipe_sampler_view viewTempl
, *view
;
665 boolean is_stencil
, is_depth
;
667 /* Give up if textures are not set. */
674 assert(!is_overlap(srcx
, srcx
+ width
, srcy
, srcy
+ height
,
675 dstx
, dstx
+ width
, dsty
, dsty
+ height
));
677 assert(dst
->format
== src
->format
);
679 assert(src
->target
< PIPE_MAX_TEXTURE_TYPES
);
681 /* Is this a ZS format? */
682 is_depth
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 0) != 0;
683 is_stencil
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 1) != 0;
685 if (is_depth
|| is_stencil
)
686 bind
= PIPE_BIND_DEPTH_STENCIL
;
688 bind
= PIPE_BIND_RENDER_TARGET
;
690 /* Check if we can sample from and render to the surfaces. */
691 /* (assuming copying a stencil buffer is not possible) */
692 if ((!ignore_stencil
&& is_stencil
) ||
693 !screen
->is_format_supported(screen
, dst
->format
, dst
->target
,
694 dst
->nr_samples
, bind
, 0) ||
695 !screen
->is_format_supported(screen
, src
->format
, src
->target
,
696 src
->nr_samples
, PIPE_BIND_SAMPLER_VIEW
, 0)) {
697 util_resource_copy_region(pipe
, dst
, subdst
, dstx
, dsty
, dstz
,
698 src
, subsrc
, srcx
, srcy
, srcz
, width
, height
);
703 dstsurf
= screen
->get_tex_surface(screen
, dst
,
704 subdst
.face
, subdst
.level
, dstz
,
707 /* Check whether the states are properly saved. */
708 blitter_check_saved_CSOs(ctx
);
709 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
710 assert(blitter
->saved_num_sampler_views
!= ~0);
711 assert(blitter
->saved_num_sampler_states
!= ~0);
713 /* Initialize framebuffer state. */
714 fb_state
.width
= dstsurf
->width
;
715 fb_state
.height
= dstsurf
->height
;
718 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
719 pipe
->bind_depth_stencil_alpha_state(pipe
,
720 ctx
->dsa_write_depth_keep_stencil
);
721 pipe
->bind_fs_state(pipe
,
722 blitter_get_fs_texfetch_depth(ctx
, src
->target
));
724 fb_state
.nr_cbufs
= 0;
725 fb_state
.zsbuf
= dstsurf
;
727 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
728 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
729 pipe
->bind_fs_state(pipe
,
730 blitter_get_fs_texfetch_col(ctx
, src
->target
));
732 fb_state
.nr_cbufs
= 1;
733 fb_state
.cbufs
[0] = dstsurf
;
737 /* Initialize sampler view. */
738 u_sampler_view_default_template(&viewTempl
, src
, src
->format
);
739 view
= pipe
->create_sampler_view(pipe
, src
, &viewTempl
);
741 if (ctx
->sampler_view
) {
742 pipe_sampler_view_reference(&ctx
->sampler_view
, NULL
);
744 ctx
->sampler_view
= view
;
746 /* Set rasterizer state, shaders, and textures. */
747 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
748 pipe
->bind_vs_state(pipe
, ctx
->vs_tex
);
749 pipe
->bind_fragment_sampler_states(pipe
, 1,
750 blitter_get_sampler_state(ctx
, subsrc
.level
));
751 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
752 pipe
->set_fragment_sampler_views(pipe
, 1, &view
);
753 pipe
->set_framebuffer_state(pipe
, &fb_state
);
755 /* Set texture coordinates. */
756 switch (src
->target
) {
757 case PIPE_TEXTURE_1D
:
758 case PIPE_TEXTURE_2D
:
759 blitter_set_texcoords_2d(ctx
, src
, subsrc
,
760 srcx
, srcy
, srcx
+width
, srcy
+height
);
762 case PIPE_TEXTURE_3D
:
763 blitter_set_texcoords_3d(ctx
, src
, subsrc
, srcz
,
764 srcx
, srcy
, srcx
+width
, srcy
+height
);
766 case PIPE_TEXTURE_CUBE
:
767 blitter_set_texcoords_cube(ctx
, src
, subsrc
,
768 srcx
, srcy
, srcx
+width
, srcy
+height
);
775 blitter_set_rectangle(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
,
776 dstsurf
->width
, dstsurf
->height
, 0);
777 blitter_draw_quad(ctx
);
778 blitter_restore_CSOs(ctx
);
780 pipe_surface_reference(&dstsurf
, NULL
);
783 /* Clear a region of a color surface to a constant value. */
784 void util_blitter_clear_render_target(struct blitter_context
*blitter
,
785 struct pipe_surface
*dstsurf
,
787 unsigned dstx
, unsigned dsty
,
788 unsigned width
, unsigned height
)
790 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
791 struct pipe_context
*pipe
= ctx
->pipe
;
792 struct pipe_framebuffer_state fb_state
;
794 assert(dstsurf
->texture
);
795 if (!dstsurf
->texture
)
798 /* check the saved state */
799 blitter_check_saved_CSOs(ctx
);
800 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
803 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
804 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
805 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
806 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 1));
807 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
808 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
810 /* set a framebuffer state */
811 fb_state
.width
= dstsurf
->width
;
812 fb_state
.height
= dstsurf
->height
;
813 fb_state
.nr_cbufs
= 1;
814 fb_state
.cbufs
[0] = dstsurf
;
816 pipe
->set_framebuffer_state(pipe
, &fb_state
);
818 blitter_set_clear_color(ctx
, rgba
);
819 blitter_set_rectangle(ctx
, 0, 0, width
, height
, dstsurf
->width
, dstsurf
->height
, 0);
820 blitter_draw_quad(ctx
);
821 blitter_restore_CSOs(ctx
);
824 /* Clear a region of a depth stencil surface. */
825 void util_blitter_clear_depth_stencil(struct blitter_context
*blitter
,
826 struct pipe_surface
*dstsurf
,
827 unsigned clear_flags
,
830 unsigned dstx
, unsigned dsty
,
831 unsigned width
, unsigned height
)
833 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
834 struct pipe_context
*pipe
= ctx
->pipe
;
835 struct pipe_framebuffer_state fb_state
;
836 struct pipe_stencil_ref sr
= { { 0 } };
838 assert(dstsurf
->texture
);
839 if (!dstsurf
->texture
)
842 /* check the saved state */
843 blitter_check_saved_CSOs(ctx
);
844 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
847 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
848 if ((clear_flags
& PIPE_CLEAR_DEPTHSTENCIL
) == PIPE_CLEAR_DEPTHSTENCIL
) {
849 sr
.ref_value
[0] = stencil
& 0xff;
850 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
851 pipe
->set_stencil_ref(pipe
, &sr
);
853 else if (clear_flags
& PIPE_CLEAR_DEPTH
) {
854 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_keep_stencil
);
856 else if (clear_flags
& PIPE_CLEAR_STENCIL
) {
857 sr
.ref_value
[0] = stencil
& 0xff;
858 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_write_stencil
);
859 pipe
->set_stencil_ref(pipe
, &sr
);
862 /* hmm that should be illegal probably, or make it a no-op somewhere */
863 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
865 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
866 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 0));
867 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
868 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
870 /* set a framebuffer state */
871 fb_state
.width
= dstsurf
->width
;
872 fb_state
.height
= dstsurf
->height
;
873 fb_state
.nr_cbufs
= 0;
874 fb_state
.cbufs
[0] = 0;
875 fb_state
.zsbuf
= dstsurf
;
876 pipe
->set_framebuffer_state(pipe
, &fb_state
);
878 blitter_set_rectangle(ctx
, 0, 0, width
, height
, dstsurf
->width
, dstsurf
->height
, depth
);
879 blitter_draw_quad(ctx
);
880 blitter_restore_CSOs(ctx
);