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, resource_copy_region,
30 * and resource_fill_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_rect.h"
48 #include "util/u_sampler.h"
49 #include "util/u_simple_shaders.h"
50 #include "util/u_surface.h"
51 #include "util/u_texture.h"
53 #define INVALID_PTR ((void*)~0)
55 struct blitter_context_priv
57 struct blitter_context blitter
;
59 struct pipe_context
*pipe
; /**< pipe context */
60 struct pipe_resource
*vbuf
; /**< quad */
62 float vertices
[4][2][4]; /**< {pos, color} or {pos, texcoord} */
64 /* Templates for various state objects. */
65 struct pipe_sampler_state template_sampler_state
;
67 /* Constant state objects. */
69 void *vs_col
; /**< Vertex shader which passes {pos, color} to the output */
70 void *vs_tex
; /**< Vertex shader which passes {pos, texcoord} to the output.*/
72 /* Fragment shaders. */
73 /* FS which outputs a color to multiple color buffers. */
74 void *fs_col
[PIPE_MAX_COLOR_BUFS
];
76 /* FS which outputs a color from a texture,
77 where the index is PIPE_TEXTURE_* to be sampled. */
78 void *fs_texfetch_col
[PIPE_MAX_TEXTURE_TYPES
];
80 /* FS which outputs a depth from a texture,
81 where the index is PIPE_TEXTURE_* to be sampled. */
82 void *fs_texfetch_depth
[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
;
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
);
165 /* The DSA state objects which write depth and stencil are created
169 sampler_state
= &ctx
->template_sampler_state
;
170 sampler_state
->wrap_s
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
171 sampler_state
->wrap_t
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
172 sampler_state
->wrap_r
= PIPE_TEX_WRAP_CLAMP_TO_EDGE
;
173 sampler_state
->normalized_coords
= TRUE
;
174 /* The sampler state objects which sample from a specified mipmap level
175 * are created on-demand. */
177 /* rasterizer state */
178 memset(&rs_state
, 0, sizeof(rs_state
));
179 rs_state
.front_winding
= PIPE_WINDING_CW
;
180 rs_state
.cull_mode
= PIPE_WINDING_NONE
;
181 rs_state
.gl_rasterization_rules
= 1;
182 rs_state
.flatshade
= 1;
183 ctx
->rs_state
= pipe
->create_rasterizer_state(pipe
, &rs_state
);
185 /* vertex elements state */
186 memset(&velem
[0], 0, sizeof(velem
[0]) * 2);
187 for (i
= 0; i
< 2; i
++) {
188 velem
[i
].src_offset
= i
* 4 * sizeof(float);
189 velem
[i
].instance_divisor
= 0;
190 velem
[i
].vertex_buffer_index
= 0;
191 velem
[i
].src_format
= PIPE_FORMAT_R32G32B32A32_FLOAT
;
193 ctx
->velem_state
= pipe
->create_vertex_elements_state(pipe
, 2, &velem
[0]);
195 /* fragment shaders are created on-demand */
199 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
200 TGSI_SEMANTIC_COLOR
};
201 const uint semantic_indices
[] = { 0, 0 };
203 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
207 const uint semantic_names
[] = { TGSI_SEMANTIC_POSITION
,
208 TGSI_SEMANTIC_GENERIC
};
209 const uint semantic_indices
[] = { 0, 0 };
211 util_make_vertex_passthrough_shader(pipe
, 2, semantic_names
,
215 /* set invariant vertex coordinates */
216 for (i
= 0; i
< 4; i
++)
217 ctx
->vertices
[i
][0][3] = 1; /*v.w*/
219 /* create the vertex buffer */
220 ctx
->vbuf
= pipe_buffer_create(ctx
->pipe
->screen
,
221 PIPE_BIND_VERTEX_BUFFER
,
222 sizeof(ctx
->vertices
));
224 return &ctx
->blitter
;
227 void util_blitter_destroy(struct blitter_context
*blitter
)
229 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
230 struct pipe_context
*pipe
= ctx
->pipe
;
233 pipe
->delete_blend_state(pipe
, ctx
->blend_write_color
);
234 pipe
->delete_blend_state(pipe
, ctx
->blend_keep_color
);
235 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
236 pipe
->delete_depth_stencil_alpha_state(pipe
,
237 ctx
->dsa_write_depth_keep_stencil
);
238 pipe
->delete_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
240 pipe
->delete_rasterizer_state(pipe
, ctx
->rs_state
);
241 pipe
->delete_vs_state(pipe
, ctx
->vs_col
);
242 pipe
->delete_vs_state(pipe
, ctx
->vs_tex
);
243 pipe
->delete_vertex_elements_state(pipe
, ctx
->velem_state
);
245 for (i
= 0; i
< PIPE_MAX_TEXTURE_TYPES
; i
++) {
246 if (ctx
->fs_texfetch_col
[i
])
247 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_col
[i
]);
248 if (ctx
->fs_texfetch_depth
[i
])
249 pipe
->delete_fs_state(pipe
, ctx
->fs_texfetch_depth
[i
]);
252 for (i
= 0; i
< PIPE_MAX_COLOR_BUFS
&& ctx
->fs_col
[i
]; i
++)
254 pipe
->delete_fs_state(pipe
, ctx
->fs_col
[i
]);
256 for (i
= 0; i
< PIPE_MAX_TEXTURE_LEVELS
; i
++)
257 if (ctx
->sampler_state
[i
])
258 pipe
->delete_sampler_state(pipe
, ctx
->sampler_state
[i
]);
260 if (ctx
->sampler_view
) {
261 pipe_sampler_view_reference(&ctx
->sampler_view
, NULL
);
264 pipe_resource_reference(&ctx
->vbuf
, NULL
);
268 static void blitter_check_saved_CSOs(struct blitter_context_priv
*ctx
)
270 /* make sure these CSOs have been saved */
271 assert(ctx
->blitter
.saved_blend_state
!= INVALID_PTR
&&
272 ctx
->blitter
.saved_dsa_state
!= INVALID_PTR
&&
273 ctx
->blitter
.saved_rs_state
!= INVALID_PTR
&&
274 ctx
->blitter
.saved_fs
!= INVALID_PTR
&&
275 ctx
->blitter
.saved_vs
!= INVALID_PTR
&&
276 ctx
->blitter
.saved_velem_state
!= INVALID_PTR
);
279 static void blitter_restore_CSOs(struct blitter_context_priv
*ctx
)
281 struct pipe_context
*pipe
= ctx
->pipe
;
283 /* restore the state objects which are always required to be saved */
284 pipe
->bind_blend_state(pipe
, ctx
->blitter
.saved_blend_state
);
285 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->blitter
.saved_dsa_state
);
286 pipe
->bind_rasterizer_state(pipe
, ctx
->blitter
.saved_rs_state
);
287 pipe
->bind_fs_state(pipe
, ctx
->blitter
.saved_fs
);
288 pipe
->bind_vs_state(pipe
, ctx
->blitter
.saved_vs
);
289 pipe
->bind_vertex_elements_state(pipe
, ctx
->blitter
.saved_velem_state
);
291 ctx
->blitter
.saved_blend_state
= INVALID_PTR
;
292 ctx
->blitter
.saved_dsa_state
= INVALID_PTR
;
293 ctx
->blitter
.saved_rs_state
= INVALID_PTR
;
294 ctx
->blitter
.saved_fs
= INVALID_PTR
;
295 ctx
->blitter
.saved_vs
= INVALID_PTR
;
296 ctx
->blitter
.saved_velem_state
= INVALID_PTR
;
298 pipe
->set_stencil_ref(pipe
, &ctx
->blitter
.saved_stencil_ref
);
300 pipe
->set_viewport_state(pipe
, &ctx
->blitter
.saved_viewport
);
301 pipe
->set_clip_state(pipe
, &ctx
->blitter
.saved_clip
);
303 /* restore the state objects which are required to be saved before copy/fill
305 if (ctx
->blitter
.saved_fb_state
.nr_cbufs
!= ~0) {
306 pipe
->set_framebuffer_state(pipe
, &ctx
->blitter
.saved_fb_state
);
307 ctx
->blitter
.saved_fb_state
.nr_cbufs
= ~0;
310 if (ctx
->blitter
.saved_num_sampler_states
!= ~0) {
311 pipe
->bind_fragment_sampler_states(pipe
,
312 ctx
->blitter
.saved_num_sampler_states
,
313 ctx
->blitter
.saved_sampler_states
);
314 ctx
->blitter
.saved_num_sampler_states
= ~0;
317 if (ctx
->blitter
.saved_num_sampler_views
!= ~0) {
318 pipe
->set_fragment_sampler_views(pipe
,
319 ctx
->blitter
.saved_num_sampler_views
,
320 ctx
->blitter
.saved_sampler_views
);
321 ctx
->blitter
.saved_num_sampler_views
= ~0;
324 if (ctx
->blitter
.saved_num_vertex_buffers
!= ~0) {
325 pipe
->set_vertex_buffers(pipe
,
326 ctx
->blitter
.saved_num_vertex_buffers
,
327 ctx
->blitter
.saved_vertex_buffers
);
328 ctx
->blitter
.saved_num_vertex_buffers
= ~0;
332 static void blitter_set_rectangle(struct blitter_context_priv
*ctx
,
333 unsigned x1
, unsigned y1
,
334 unsigned x2
, unsigned y2
,
335 unsigned width
, unsigned height
,
340 /* set vertex positions */
341 ctx
->vertices
[0][0][0] = (float)x1
/ width
* 2.0f
- 1.0f
; /*v0.x*/
342 ctx
->vertices
[0][0][1] = (float)y1
/ height
* 2.0f
- 1.0f
; /*v0.y*/
344 ctx
->vertices
[1][0][0] = (float)x2
/ width
* 2.0f
- 1.0f
; /*v1.x*/
345 ctx
->vertices
[1][0][1] = (float)y1
/ height
* 2.0f
- 1.0f
; /*v1.y*/
347 ctx
->vertices
[2][0][0] = (float)x2
/ width
* 2.0f
- 1.0f
; /*v2.x*/
348 ctx
->vertices
[2][0][1] = (float)y2
/ height
* 2.0f
- 1.0f
; /*v2.y*/
350 ctx
->vertices
[3][0][0] = (float)x1
/ width
* 2.0f
- 1.0f
; /*v3.x*/
351 ctx
->vertices
[3][0][1] = (float)y2
/ height
* 2.0f
- 1.0f
; /*v3.y*/
353 for (i
= 0; i
< 4; i
++)
354 ctx
->vertices
[i
][0][2] = depth
; /*z*/
357 ctx
->viewport
.scale
[0] = 0.5f
* width
;
358 ctx
->viewport
.scale
[1] = 0.5f
* height
;
359 ctx
->viewport
.scale
[2] = 1.0f
;
360 ctx
->viewport
.scale
[3] = 1.0f
;
361 ctx
->viewport
.translate
[0] = 0.5f
* width
;
362 ctx
->viewport
.translate
[1] = 0.5f
* height
;
363 ctx
->viewport
.translate
[2] = 0.0f
;
364 ctx
->viewport
.translate
[3] = 0.0f
;
365 ctx
->pipe
->set_viewport_state(ctx
->pipe
, &ctx
->viewport
);
368 ctx
->pipe
->set_clip_state(ctx
->pipe
, &ctx
->clip
);
371 static void blitter_set_clear_color(struct blitter_context_priv
*ctx
,
376 for (i
= 0; i
< 4; i
++) {
377 ctx
->vertices
[i
][1][0] = rgba
[0];
378 ctx
->vertices
[i
][1][1] = rgba
[1];
379 ctx
->vertices
[i
][1][2] = rgba
[2];
380 ctx
->vertices
[i
][1][3] = rgba
[3];
384 static void blitter_set_texcoords_2d(struct blitter_context_priv
*ctx
,
385 struct pipe_surface
*surf
,
386 unsigned x1
, unsigned y1
,
387 unsigned x2
, unsigned y2
)
390 float s1
= x1
/ (float)surf
->width
;
391 float t1
= y1
/ (float)surf
->height
;
392 float s2
= x2
/ (float)surf
->width
;
393 float t2
= y2
/ (float)surf
->height
;
395 ctx
->vertices
[0][1][0] = s1
; /*t0.s*/
396 ctx
->vertices
[0][1][1] = t1
; /*t0.t*/
398 ctx
->vertices
[1][1][0] = s2
; /*t1.s*/
399 ctx
->vertices
[1][1][1] = t1
; /*t1.t*/
401 ctx
->vertices
[2][1][0] = s2
; /*t2.s*/
402 ctx
->vertices
[2][1][1] = t2
; /*t2.t*/
404 ctx
->vertices
[3][1][0] = s1
; /*t3.s*/
405 ctx
->vertices
[3][1][1] = t2
; /*t3.t*/
407 for (i
= 0; i
< 4; i
++) {
408 ctx
->vertices
[i
][1][2] = 0; /*r*/
409 ctx
->vertices
[i
][1][3] = 1; /*q*/
413 static void blitter_set_texcoords_3d(struct blitter_context_priv
*ctx
,
414 struct pipe_surface
*surf
,
415 unsigned x1
, unsigned y1
,
416 unsigned x2
, unsigned y2
)
419 float depth
= u_minify(surf
->texture
->depth0
, surf
->level
);
420 float r
= surf
->zslice
/ depth
;
422 blitter_set_texcoords_2d(ctx
, surf
, x1
, y1
, x2
, y2
);
424 for (i
= 0; i
< 4; i
++)
425 ctx
->vertices
[i
][1][2] = r
; /*r*/
428 static void blitter_set_texcoords_cube(struct blitter_context_priv
*ctx
,
429 struct pipe_surface
*surf
,
430 unsigned x1
, unsigned y1
,
431 unsigned x2
, unsigned y2
)
434 float s1
= x1
/ (float)surf
->width
;
435 float t1
= y1
/ (float)surf
->height
;
436 float s2
= x2
/ (float)surf
->width
;
437 float t2
= y2
/ (float)surf
->height
;
449 util_map_texcoords2d_onto_cubemap(surf
->face
,
450 /* pointer, stride in floats */
452 &ctx
->vertices
[0][1][0], 8);
454 for (i
= 0; i
< 4; i
++)
455 ctx
->vertices
[i
][1][3] = 1; /*q*/
458 static void blitter_draw_quad(struct blitter_context_priv
*ctx
)
460 struct pipe_context
*pipe
= ctx
->pipe
;
462 /* write vertices and draw them */
463 pipe_buffer_write(pipe
, ctx
->vbuf
,
464 0, sizeof(ctx
->vertices
), ctx
->vertices
);
466 util_draw_vertex_buffer(pipe
, ctx
->vbuf
, 0, PIPE_PRIM_TRIANGLE_FAN
,
468 2); /* attribs/vert */
472 void **blitter_get_sampler_state(struct blitter_context_priv
*ctx
,
475 struct pipe_context
*pipe
= ctx
->pipe
;
476 struct pipe_sampler_state
*sampler_state
= &ctx
->template_sampler_state
;
478 assert(miplevel
< PIPE_MAX_TEXTURE_LEVELS
);
480 /* Create the sampler state on-demand. */
481 if (!ctx
->sampler_state
[miplevel
]) {
482 sampler_state
->lod_bias
= miplevel
;
483 sampler_state
->min_lod
= miplevel
;
484 sampler_state
->max_lod
= miplevel
;
486 ctx
->sampler_state
[miplevel
] = pipe
->create_sampler_state(pipe
,
490 /* Return void** so that it can be passed to bind_fragment_sampler_states
492 return &ctx
->sampler_state
[miplevel
];
496 void *blitter_get_fs_col(struct blitter_context_priv
*ctx
, unsigned num_cbufs
)
498 struct pipe_context
*pipe
= ctx
->pipe
;
499 unsigned index
= num_cbufs
? num_cbufs
- 1 : 0;
501 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
503 if (!ctx
->fs_col
[index
])
505 util_make_fragment_clonecolor_shader(pipe
, num_cbufs
);
507 return ctx
->fs_col
[index
];
511 void *blitter_get_fs_texfetch_col(struct blitter_context_priv
*ctx
,
514 struct pipe_context
*pipe
= ctx
->pipe
;
516 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
518 /* Create the fragment shader on-demand. */
519 if (!ctx
->fs_texfetch_col
[tex_target
]) {
520 switch (tex_target
) {
521 case PIPE_TEXTURE_1D
:
522 ctx
->fs_texfetch_col
[PIPE_TEXTURE_1D
] =
523 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_1D
);
525 case PIPE_TEXTURE_2D
:
526 ctx
->fs_texfetch_col
[PIPE_TEXTURE_2D
] =
527 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_2D
);
529 case PIPE_TEXTURE_3D
:
530 ctx
->fs_texfetch_col
[PIPE_TEXTURE_3D
] =
531 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_3D
);
533 case PIPE_TEXTURE_CUBE
:
534 ctx
->fs_texfetch_col
[PIPE_TEXTURE_CUBE
] =
535 util_make_fragment_tex_shader(pipe
, TGSI_TEXTURE_CUBE
);
541 return ctx
->fs_texfetch_col
[tex_target
];
545 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv
*ctx
,
548 struct pipe_context
*pipe
= ctx
->pipe
;
550 assert(tex_target
< PIPE_MAX_TEXTURE_TYPES
);
552 /* Create the fragment shader on-demand. */
553 if (!ctx
->fs_texfetch_depth
[tex_target
]) {
554 switch (tex_target
) {
555 case PIPE_TEXTURE_1D
:
556 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_1D
] =
557 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_1D
);
559 case PIPE_TEXTURE_2D
:
560 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_2D
] =
561 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_2D
);
563 case PIPE_TEXTURE_3D
:
564 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_3D
] =
565 util_make_fragment_tex_shader_writedepth(pipe
, TGSI_TEXTURE_3D
);
567 case PIPE_TEXTURE_CUBE
:
568 ctx
->fs_texfetch_depth
[PIPE_TEXTURE_CUBE
] =
569 util_make_fragment_tex_shader_writedepth(pipe
,TGSI_TEXTURE_CUBE
);
575 return ctx
->fs_texfetch_depth
[tex_target
];
578 void util_blitter_clear(struct blitter_context
*blitter
,
579 unsigned width
, unsigned height
,
581 unsigned clear_buffers
,
583 double depth
, unsigned stencil
)
585 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
586 struct pipe_context
*pipe
= ctx
->pipe
;
587 struct pipe_stencil_ref sr
= { { 0 } };
589 assert(num_cbufs
<= PIPE_MAX_COLOR_BUFS
);
591 blitter_check_saved_CSOs(ctx
);
594 if (clear_buffers
& PIPE_CLEAR_COLOR
)
595 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
597 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
599 if (clear_buffers
& PIPE_CLEAR_DEPTHSTENCIL
) {
600 sr
.ref_value
[0] = stencil
& 0xff;
601 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_write_depth_stencil
);
602 pipe
->set_stencil_ref(pipe
, &sr
);
605 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
607 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
608 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
609 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, num_cbufs
));
610 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
612 blitter_set_clear_color(ctx
, rgba
);
613 blitter_set_rectangle(ctx
, 0, 0, width
, height
, width
, height
, depth
);
614 blitter_draw_quad(ctx
);
615 blitter_restore_CSOs(ctx
);
619 is_overlap(unsigned sx1
, unsigned sx2
, unsigned sy1
, unsigned sy2
,
620 unsigned dx1
, unsigned dx2
, unsigned dy1
, unsigned dy2
)
622 if (sx1
>= dx2
|| sx2
<= dx1
|| sy1
>= dy2
|| sy2
<= dy1
) {
629 static void util_blitter_do_copy(struct blitter_context
*blitter
,
630 struct pipe_surface
*dst
,
631 unsigned dstx
, unsigned dsty
,
632 struct pipe_surface
*src
,
633 unsigned srcx
, unsigned srcy
,
634 unsigned width
, unsigned height
,
637 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
638 struct pipe_context
*pipe
= ctx
->pipe
;
639 struct pipe_framebuffer_state fb_state
;
640 struct pipe_sampler_view viewTempl
, *view
;
642 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
643 assert(blitter
->saved_num_sampler_views
!= ~0);
644 assert(blitter
->saved_num_sampler_states
!= ~0);
645 assert(src
->texture
->target
< PIPE_MAX_TEXTURE_TYPES
);
648 fb_state
.width
= dst
->width
;
649 fb_state
.height
= dst
->height
;
652 pipe
->bind_blend_state(pipe
, ctx
->blend_keep_color
);
653 pipe
->bind_depth_stencil_alpha_state(pipe
,
654 ctx
->dsa_write_depth_keep_stencil
);
655 pipe
->bind_fs_state(pipe
,
656 blitter_get_fs_texfetch_depth(ctx
, src
->texture
->target
));
658 fb_state
.nr_cbufs
= 0;
659 fb_state
.zsbuf
= dst
;
661 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
662 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
663 pipe
->bind_fs_state(pipe
,
664 blitter_get_fs_texfetch_col(ctx
, src
->texture
->target
));
666 fb_state
.nr_cbufs
= 1;
667 fb_state
.cbufs
[0] = dst
;
671 u_sampler_view_default_template(&viewTempl
,
673 src
->texture
->format
);
674 view
= pipe
->create_sampler_view(pipe
,
678 if (ctx
->sampler_view
) {
679 pipe_sampler_view_reference(&ctx
->sampler_view
, NULL
);
681 ctx
->sampler_view
= view
;
683 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
684 pipe
->bind_vs_state(pipe
, ctx
->vs_tex
);
685 pipe
->bind_fragment_sampler_states(pipe
, 1,
686 blitter_get_sampler_state(ctx
, src
->level
));
687 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
688 pipe
->set_fragment_sampler_views(pipe
, 1, &view
);
689 pipe
->set_framebuffer_state(pipe
, &fb_state
);
691 /* set texture coordinates */
692 switch (src
->texture
->target
) {
693 case PIPE_TEXTURE_1D
:
694 case PIPE_TEXTURE_2D
:
695 blitter_set_texcoords_2d(ctx
, src
, srcx
, srcy
,
696 srcx
+width
, srcy
+height
);
698 case PIPE_TEXTURE_3D
:
699 blitter_set_texcoords_3d(ctx
, src
, srcx
, srcy
,
700 srcx
+width
, srcy
+height
);
702 case PIPE_TEXTURE_CUBE
:
703 blitter_set_texcoords_cube(ctx
, src
, srcx
, srcy
,
704 srcx
+width
, srcy
+height
);
710 blitter_set_rectangle(ctx
, dstx
, dsty
, dstx
+width
, dsty
+height
, dst
->width
, dst
->height
, 0);
711 blitter_draw_quad(ctx
);
716 void util_blitter_copy(struct blitter_context
*blitter
,
717 struct pipe_surface
*dst
,
718 unsigned dstx
, unsigned dsty
,
719 struct pipe_surface
*src
,
720 unsigned srcx
, unsigned srcy
,
721 unsigned width
, unsigned height
,
722 boolean ignore_stencil
)
724 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
725 struct pipe_context
*pipe
= ctx
->pipe
;
726 struct pipe_screen
*screen
= pipe
->screen
;
727 boolean is_stencil
, is_depth
;
728 unsigned dst_tex_usage
;
730 /* give up if textures are not set */
731 assert(dst
->texture
&& src
->texture
);
732 if (!dst
->texture
|| !src
->texture
)
735 if (dst
->texture
== src
->texture
) {
736 assert(!is_overlap(srcx
, srcx
+ width
, srcy
, srcy
+ height
,
737 dstx
, dstx
+ width
, dsty
, dsty
+ height
))
741 is_depth
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 0) != 0;
742 is_stencil
= util_format_get_component_bits(src
->format
, UTIL_FORMAT_COLORSPACE_ZS
, 1) != 0;
743 dst_tex_usage
= is_depth
|| is_stencil
? PIPE_BIND_DEPTH_STENCIL
:
744 PIPE_BIND_RENDER_TARGET
;
746 /* check if we can sample from and render to the surfaces */
747 /* (assuming copying a stencil buffer is not possible) */
748 if ((!ignore_stencil
&& is_stencil
) ||
749 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
750 dst
->texture
->nr_samples
, dst_tex_usage
, 0) ||
751 !screen
->is_format_supported(screen
, src
->format
, src
->texture
->target
,
752 src
->texture
->nr_samples
, PIPE_BIND_SAMPLER_VIEW
, 0)) {
753 struct pipe_subresource subdst
, subsrc
;
754 subdst
.face
= dst
->face
;
755 subdst
.level
= dst
->level
;
756 subsrc
.face
= src
->face
;
757 subsrc
.level
= src
->level
;
758 util_resource_copy_region(pipe
, dst
, subdst
, dstx
, dsty
, dst
->zslice
,
759 src
, subsrc
, srcx
, srcy
, src
->zslice
,
764 /* check whether the states are properly saved */
765 blitter_check_saved_CSOs(ctx
);
766 util_blitter_do_copy(blitter
,
769 width
, height
, is_depth
);
770 blitter_restore_CSOs(ctx
);
773 void util_blitter_fill(struct blitter_context
*blitter
,
774 struct pipe_surface
*dst
,
775 unsigned dstx
, unsigned dsty
,
776 unsigned width
, unsigned height
,
779 struct blitter_context_priv
*ctx
= (struct blitter_context_priv
*)blitter
;
780 struct pipe_context
*pipe
= ctx
->pipe
;
781 struct pipe_screen
*screen
= pipe
->screen
;
782 struct pipe_framebuffer_state fb_state
;
784 ubyte ub_rgba
[4] = {0};
785 union util_color color
;
788 assert(dst
->texture
);
792 /* check if we can render to the surface */
793 if (util_format_is_depth_or_stencil(dst
->format
) || /* unlikely, but you never know */
794 !screen
->is_format_supported(screen
, dst
->format
, dst
->texture
->target
,
795 dst
->texture
->nr_samples
,
796 PIPE_BIND_RENDER_TARGET
, 0)) {
797 struct pipe_subresource subdst
;
798 subdst
.face
= dst
->face
;
799 subdst
.level
= dst
->level
;
800 util_resource_fill_region(pipe
, dst
->texture
, subdst
, dstx
, dsty
,
801 dst
->zslice
, width
, height
, value
);
805 /* unpack the color */
807 util_unpack_color_ub(dst
->format
, &color
,
808 ub_rgba
, ub_rgba
+1, ub_rgba
+2, ub_rgba
+3);
809 for (i
= 0; i
< 4; i
++)
810 rgba
[i
] = ubyte_to_float(ub_rgba
[i
]);
812 /* check the saved state */
813 blitter_check_saved_CSOs(ctx
);
814 assert(blitter
->saved_fb_state
.nr_cbufs
!= ~0);
817 pipe
->bind_blend_state(pipe
, ctx
->blend_write_color
);
818 pipe
->bind_depth_stencil_alpha_state(pipe
, ctx
->dsa_keep_depth_stencil
);
819 pipe
->bind_rasterizer_state(pipe
, ctx
->rs_state
);
820 pipe
->bind_fs_state(pipe
, blitter_get_fs_col(ctx
, 1));
821 pipe
->bind_vs_state(pipe
, ctx
->vs_col
);
822 pipe
->bind_vertex_elements_state(pipe
, ctx
->velem_state
);
824 /* set a framebuffer state */
825 fb_state
.width
= dst
->width
;
826 fb_state
.height
= dst
->height
;
827 fb_state
.nr_cbufs
= 1;
828 fb_state
.cbufs
[0] = dst
;
830 pipe
->set_framebuffer_state(pipe
, &fb_state
);
832 blitter_set_clear_color(ctx
, rgba
);
833 blitter_set_rectangle(ctx
, 0, 0, width
, height
, dst
->width
, dst
->height
, 0);
834 blitter_draw_quad(ctx
);
835 blitter_restore_CSOs(ctx
);