gallium/u_blitter: handle PIPE_TEXTURE_CUBE_ARRAY in is_box_inside_resource
[mesa.git] / src / gallium / auxiliary / util / u_blitter.c
1 /**************************************************************************
2 *
3 * Copyright 2009 Marek Olšák <maraeo@gmail.com>
4 *
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:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
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.
24 *
25 **************************************************************************/
26
27 /**
28 * @file
29 * Blitter utility to facilitate acceleration of the clear, clear_render_target,
30 * clear_depth_stencil, resource_copy_region, and blit functions.
31 *
32 * @author Marek Olšák
33 */
34
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"
40
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"
51
52 #define INVALID_PTR ((void*)~0)
53
54 struct blitter_context_priv
55 {
56 struct blitter_context base;
57
58 struct u_upload_mgr *upload;
59
60 float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
61
62 /* Templates for various state objects. */
63
64 /* Constant state objects. */
65 /* Vertex shaders. */
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.*/
68
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];
73
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];
77
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];
83
84 /* FS which outputs one sample from a multisample texture. */
85 void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES];
86 void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
87 void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
88 void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
89
90 /* Blend state. */
91 void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */
92
93 /* Depth stencil alpha state. */
94 void *dsa_write_depth_stencil;
95 void *dsa_write_depth_keep_stencil;
96 void *dsa_keep_depth_stencil;
97 void *dsa_keep_depth_write_stencil;
98
99 /* Vertex elements states. */
100 void *velem_state;
101 void *velem_uint_state;
102 void *velem_sint_state;
103 void *velem_state_readbuf;
104
105 /* Sampler state. */
106 void *sampler_state, *sampler_state_linear;
107
108 /* Rasterizer state. */
109 void *rs_state, *rs_state_scissor, *rs_discard_state;
110
111 /* Viewport state. */
112 struct pipe_viewport_state viewport;
113
114 /* Destination surface dimensions. */
115 unsigned dst_width;
116 unsigned dst_height;
117
118 boolean has_geometry_shader;
119 boolean vertex_has_integers;
120 boolean has_stream_out;
121 boolean has_stencil_export;
122 boolean has_texture_multisample;
123
124 /* The Draw module overrides these functions.
125 * Always create the blitter before Draw. */
126 void (*bind_fs_state)(struct pipe_context *, void *);
127 void (*delete_fs_state)(struct pipe_context *, void *);
128 };
129
130 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
131 {
132 struct blitter_context_priv *ctx;
133 struct pipe_blend_state blend;
134 struct pipe_depth_stencil_alpha_state dsa;
135 struct pipe_rasterizer_state rs_state;
136 struct pipe_sampler_state sampler_state;
137 struct pipe_vertex_element velem[2];
138 unsigned i;
139
140 ctx = CALLOC_STRUCT(blitter_context_priv);
141 if (!ctx)
142 return NULL;
143
144 ctx->base.pipe = pipe;
145 ctx->base.draw_rectangle = util_blitter_draw_rectangle;
146
147 ctx->bind_fs_state = pipe->bind_fs_state;
148 ctx->delete_fs_state = pipe->delete_fs_state;
149
150 /* init state objects for them to be considered invalid */
151 ctx->base.saved_blend_state = INVALID_PTR;
152 ctx->base.saved_dsa_state = INVALID_PTR;
153 ctx->base.saved_rs_state = INVALID_PTR;
154 ctx->base.saved_fs = INVALID_PTR;
155 ctx->base.saved_vs = INVALID_PTR;
156 ctx->base.saved_gs = INVALID_PTR;
157 ctx->base.saved_velem_state = INVALID_PTR;
158 ctx->base.saved_fb_state.nr_cbufs = ~0;
159 ctx->base.saved_num_sampler_views = ~0;
160 ctx->base.saved_num_sampler_states = ~0;
161 ctx->base.saved_num_so_targets = ~0;
162
163 ctx->has_geometry_shader =
164 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
165 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
166 ctx->vertex_has_integers =
167 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_VERTEX,
168 PIPE_SHADER_CAP_INTEGERS);
169 ctx->has_stream_out =
170 pipe->screen->get_param(pipe->screen,
171 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
172
173 ctx->has_stencil_export =
174 pipe->screen->get_param(pipe->screen,
175 PIPE_CAP_SHADER_STENCIL_EXPORT);
176
177 ctx->has_texture_multisample =
178 pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE);
179
180 /* blend state objects */
181 memset(&blend, 0, sizeof(blend));
182
183 for (i = 0; i <= PIPE_MASK_RGBA; i++) {
184 blend.rt[0].colormask = i;
185 ctx->blend[i] = pipe->create_blend_state(pipe, &blend);
186 }
187
188 /* depth stencil alpha state objects */
189 memset(&dsa, 0, sizeof(dsa));
190 ctx->dsa_keep_depth_stencil =
191 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
192
193 dsa.depth.enabled = 1;
194 dsa.depth.writemask = 1;
195 dsa.depth.func = PIPE_FUNC_ALWAYS;
196 ctx->dsa_write_depth_keep_stencil =
197 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
198
199 dsa.stencil[0].enabled = 1;
200 dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
201 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
202 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
203 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
204 dsa.stencil[0].valuemask = 0xff;
205 dsa.stencil[0].writemask = 0xff;
206 ctx->dsa_write_depth_stencil =
207 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
208
209 dsa.depth.enabled = 0;
210 dsa.depth.writemask = 0;
211 ctx->dsa_keep_depth_write_stencil =
212 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
213
214 /* sampler state */
215 memset(&sampler_state, 0, sizeof(sampler_state));
216 sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
217 sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
218 sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
219 sampler_state.normalized_coords = 1;
220 ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
221
222 sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
223 sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
224 ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
225
226 /* rasterizer state */
227 memset(&rs_state, 0, sizeof(rs_state));
228 rs_state.cull_face = PIPE_FACE_NONE;
229 rs_state.gl_rasterization_rules = 1;
230 rs_state.flatshade = 1;
231 rs_state.depth_clip = 1;
232 ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
233
234 rs_state.scissor = 1;
235 ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state);
236
237 if (ctx->has_stream_out) {
238 rs_state.scissor = 0;
239 rs_state.rasterizer_discard = 1;
240 ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
241 }
242
243 ctx->base.vb_slot = 0; /* 0 for now */
244
245 /* vertex elements states */
246 memset(&velem[0], 0, sizeof(velem[0]) * 2);
247 for (i = 0; i < 2; i++) {
248 velem[i].src_offset = i * 4 * sizeof(float);
249 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
250 velem[i].vertex_buffer_index = ctx->base.vb_slot;
251 }
252 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
253
254 if (ctx->vertex_has_integers) {
255 memset(&velem[0], 0, sizeof(velem[0]) * 2);
256 velem[0].src_offset = 0;
257 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
258 velem[0].vertex_buffer_index = ctx->base.vb_slot;
259 velem[1].src_offset = 4 * sizeof(float);
260 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_SINT;
261 velem[1].vertex_buffer_index = ctx->base.vb_slot;
262 ctx->velem_sint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
263
264 memset(&velem[0], 0, sizeof(velem[0]) * 2);
265 velem[0].src_offset = 0;
266 velem[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
267 velem[0].vertex_buffer_index = ctx->base.vb_slot;
268 velem[1].src_offset = 4 * sizeof(float);
269 velem[1].src_format = PIPE_FORMAT_R32G32B32A32_UINT;
270 velem[1].vertex_buffer_index = ctx->base.vb_slot;
271 ctx->velem_uint_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
272 }
273
274 if (ctx->has_stream_out) {
275 velem[0].src_format = PIPE_FORMAT_R32_UINT;
276 velem[0].vertex_buffer_index = ctx->base.vb_slot;
277 ctx->velem_state_readbuf = pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
278 }
279
280 /* fragment shaders are created on-demand */
281
282 /* vertex shaders */
283 {
284 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
285 TGSI_SEMANTIC_GENERIC };
286 const uint semantic_indices[] = { 0, 0 };
287 ctx->vs =
288 util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
289 semantic_indices);
290 }
291 if (ctx->has_stream_out) {
292 struct pipe_stream_output_info so;
293 const uint semantic_names[] = { TGSI_SEMANTIC_POSITION };
294 const uint semantic_indices[] = { 0 };
295
296 memset(&so, 0, sizeof(so));
297 so.num_outputs = 1;
298 so.output[0].num_components = 1;
299 so.stride[0] = 1;
300
301 ctx->vs_pos_only =
302 util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
303 semantic_indices, &so);
304 }
305
306 /* set invariant vertex coordinates */
307 for (i = 0; i < 4; i++)
308 ctx->vertices[i][0][3] = 1; /*v.w*/
309
310 ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER);
311
312 return &ctx->base;
313 }
314
315 void util_blitter_destroy(struct blitter_context *blitter)
316 {
317 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
318 struct pipe_context *pipe = blitter->pipe;
319 int i;
320
321 for (i = 0; i <= PIPE_MASK_RGBA; i++) {
322 pipe->delete_blend_state(pipe, ctx->blend[i]);
323 }
324 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
325 pipe->delete_depth_stencil_alpha_state(pipe,
326 ctx->dsa_write_depth_keep_stencil);
327 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
328 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
329
330 pipe->delete_rasterizer_state(pipe, ctx->rs_state);
331 pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor);
332 if (ctx->rs_discard_state)
333 pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
334 pipe->delete_vs_state(pipe, ctx->vs);
335 if (ctx->vs_pos_only)
336 pipe->delete_vs_state(pipe, ctx->vs_pos_only);
337 pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
338 if (ctx->vertex_has_integers) {
339 pipe->delete_vertex_elements_state(pipe, ctx->velem_sint_state);
340 pipe->delete_vertex_elements_state(pipe, ctx->velem_uint_state);
341 }
342 if (ctx->velem_state_readbuf)
343 pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf);
344
345 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
346 if (ctx->fs_texfetch_col[i])
347 ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
348 if (ctx->fs_texfetch_depth[i])
349 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
350 if (ctx->fs_texfetch_depthstencil[i])
351 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]);
352 if (ctx->fs_texfetch_stencil[i])
353 ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]);
354 }
355
356 for (i = 0; i <= PIPE_MAX_COLOR_BUFS; i++) {
357 if (ctx->fs_col[i])
358 ctx->delete_fs_state(pipe, ctx->fs_col[i]);
359 if (ctx->fs_col_int[i])
360 ctx->delete_fs_state(pipe, ctx->fs_col_int[i]);
361 }
362
363 pipe->delete_sampler_state(pipe, ctx->sampler_state);
364 pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
365 u_upload_destroy(ctx->upload);
366 FREE(ctx);
367 }
368
369 void util_blitter_set_texture_multisample(struct blitter_context *blitter,
370 boolean supported)
371 {
372 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
373
374 ctx->has_texture_multisample = supported;
375 }
376
377 static void blitter_set_running_flag(struct blitter_context_priv *ctx)
378 {
379 if (ctx->base.running) {
380 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
381 __LINE__);
382 }
383 ctx->base.running = TRUE;
384 }
385
386 static void blitter_unset_running_flag(struct blitter_context_priv *ctx)
387 {
388 if (!ctx->base.running) {
389 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
390 __LINE__);
391 }
392 ctx->base.running = FALSE;
393 }
394
395 static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx)
396 {
397 assert(ctx->base.saved_velem_state != INVALID_PTR);
398 assert(ctx->base.saved_vs != INVALID_PTR);
399 assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
400 assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0);
401 assert(ctx->base.saved_rs_state != INVALID_PTR);
402 }
403
404 static void blitter_restore_vertex_states(struct blitter_context_priv *ctx)
405 {
406 struct pipe_context *pipe = ctx->base.pipe;
407 unsigned i;
408
409 /* Vertex buffer. */
410 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1,
411 &ctx->base.saved_vertex_buffer);
412 pipe_resource_reference(&ctx->base.saved_vertex_buffer.buffer, NULL);
413
414 /* Vertex elements. */
415 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
416 ctx->base.saved_velem_state = INVALID_PTR;
417
418 /* Vertex shader. */
419 pipe->bind_vs_state(pipe, ctx->base.saved_vs);
420 ctx->base.saved_vs = INVALID_PTR;
421
422 /* Geometry shader. */
423 if (ctx->has_geometry_shader) {
424 pipe->bind_gs_state(pipe, ctx->base.saved_gs);
425 ctx->base.saved_gs = INVALID_PTR;
426 }
427
428 /* Stream outputs. */
429 if (ctx->has_stream_out) {
430 pipe->set_stream_output_targets(pipe,
431 ctx->base.saved_num_so_targets,
432 ctx->base.saved_so_targets, ~0);
433
434 for (i = 0; i < ctx->base.saved_num_so_targets; i++)
435 pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
436
437 ctx->base.saved_num_so_targets = ~0;
438 }
439
440 /* Rasterizer. */
441 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
442 ctx->base.saved_rs_state = INVALID_PTR;
443 }
444
445 static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx)
446 {
447 assert(ctx->base.saved_fs != INVALID_PTR);
448 assert(ctx->base.saved_dsa_state != INVALID_PTR);
449 assert(ctx->base.saved_blend_state != INVALID_PTR);
450 }
451
452 static void blitter_restore_fragment_states(struct blitter_context_priv *ctx)
453 {
454 struct pipe_context *pipe = ctx->base.pipe;
455
456 /* Fragment shader. */
457 ctx->bind_fs_state(pipe, ctx->base.saved_fs);
458 ctx->base.saved_fs = INVALID_PTR;
459
460 /* Depth, stencil, alpha. */
461 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
462 ctx->base.saved_dsa_state = INVALID_PTR;
463
464 /* Blend state. */
465 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
466 ctx->base.saved_blend_state = INVALID_PTR;
467
468 /* Sample mask. */
469 if (ctx->base.is_sample_mask_saved) {
470 pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask);
471 ctx->base.is_sample_mask_saved = FALSE;
472 }
473
474 /* Miscellaneous states. */
475 /* XXX check whether these are saved and whether they need to be restored
476 * (depending on the operation) */
477 pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
478 pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
479 }
480
481 static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx)
482 {
483 assert(ctx->base.saved_fb_state.nr_cbufs != ~0);
484 }
485
486 static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
487 {
488 struct pipe_context *pipe = ctx->base.pipe;
489
490 if (ctx->base.saved_render_cond_query) {
491 pipe->render_condition(pipe, NULL, 0);
492 }
493 }
494
495 static void blitter_restore_render_cond(struct blitter_context_priv *ctx)
496 {
497 struct pipe_context *pipe = ctx->base.pipe;
498
499 if (ctx->base.saved_render_cond_query) {
500 pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
501 ctx->base.saved_render_cond_mode);
502 ctx->base.saved_render_cond_query = NULL;
503 }
504 }
505
506 static void blitter_restore_fb_state(struct blitter_context_priv *ctx)
507 {
508 struct pipe_context *pipe = ctx->base.pipe;
509
510 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
511 util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
512 }
513
514 static void blitter_check_saved_textures(struct blitter_context_priv *ctx)
515 {
516 assert(ctx->base.saved_num_sampler_states != ~0);
517 assert(ctx->base.saved_num_sampler_views != ~0);
518 }
519
520 static void blitter_restore_textures(struct blitter_context_priv *ctx)
521 {
522 struct pipe_context *pipe = ctx->base.pipe;
523 unsigned i;
524
525 /* Fragment sampler states. */
526 pipe->bind_fragment_sampler_states(pipe,
527 ctx->base.saved_num_sampler_states,
528 ctx->base.saved_sampler_states);
529 ctx->base.saved_num_sampler_states = ~0;
530
531 /* Fragment sampler views. */
532 pipe->set_fragment_sampler_views(pipe,
533 ctx->base.saved_num_sampler_views,
534 ctx->base.saved_sampler_views);
535
536 for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
537 pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
538
539 ctx->base.saved_num_sampler_views = ~0;
540 }
541
542 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
543 int x1, int y1, int x2, int y2,
544 float depth)
545 {
546 int i;
547
548 /* set vertex positions */
549 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
550 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
551
552 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
553 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
554
555 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
556 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
557
558 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
559 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
560
561 for (i = 0; i < 4; i++)
562 ctx->vertices[i][0][2] = depth; /*z*/
563
564 /* viewport */
565 ctx->viewport.scale[0] = 0.5f * ctx->dst_width;
566 ctx->viewport.scale[1] = 0.5f * ctx->dst_height;
567 ctx->viewport.scale[2] = 1.0f;
568 ctx->viewport.scale[3] = 1.0f;
569 ctx->viewport.translate[0] = 0.5f * ctx->dst_width;
570 ctx->viewport.translate[1] = 0.5f * ctx->dst_height;
571 ctx->viewport.translate[2] = 0.0f;
572 ctx->viewport.translate[3] = 0.0f;
573 ctx->base.pipe->set_viewport_state(ctx->base.pipe, &ctx->viewport);
574 }
575
576 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
577 const union pipe_color_union *color)
578 {
579 int i;
580
581 if (color) {
582 for (i = 0; i < 4; i++) {
583 uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1];
584 uiverts[0] = color->ui[0];
585 uiverts[1] = color->ui[1];
586 uiverts[2] = color->ui[2];
587 uiverts[3] = color->ui[3];
588 }
589 } else {
590 for (i = 0; i < 4; i++) {
591 ctx->vertices[i][1][0] = 0;
592 ctx->vertices[i][1][1] = 0;
593 ctx->vertices[i][1][2] = 0;
594 ctx->vertices[i][1][3] = 0;
595 }
596 }
597 }
598
599 static void get_texcoords(struct pipe_sampler_view *src,
600 unsigned src_width0, unsigned src_height0,
601 int x1, int y1, int x2, int y2,
602 float out[4])
603 {
604 struct pipe_resource *tex = src->texture;
605 unsigned level = src->u.tex.first_level;
606 boolean normalized = tex->target != PIPE_TEXTURE_RECT &&
607 tex->nr_samples <= 1;
608
609 if (normalized) {
610 out[0] = x1 / (float)u_minify(src_width0, level);
611 out[1] = y1 / (float)u_minify(src_height0, level);
612 out[2] = x2 / (float)u_minify(src_width0, level);
613 out[3] = y2 / (float)u_minify(src_height0, level);
614 } else {
615 out[0] = (float) x1;
616 out[1] = (float) y1;
617 out[2] = (float) x2;
618 out[3] = (float) y2;
619 }
620 }
621
622 static void set_texcoords_in_vertices(const float coord[4],
623 float *out, unsigned stride)
624 {
625 out[0] = coord[0]; /*t0.s*/
626 out[1] = coord[1]; /*t0.t*/
627 out += stride;
628 out[0] = coord[2]; /*t1.s*/
629 out[1] = coord[1]; /*t1.t*/
630 out += stride;
631 out[0] = coord[2]; /*t2.s*/
632 out[1] = coord[3]; /*t2.t*/
633 out += stride;
634 out[0] = coord[0]; /*t3.s*/
635 out[1] = coord[3]; /*t3.t*/
636 }
637
638 static void blitter_set_texcoords(struct blitter_context_priv *ctx,
639 struct pipe_sampler_view *src,
640 unsigned src_width0, unsigned src_height0,
641 unsigned layer, unsigned sample,
642 int x1, int y1, int x2, int y2)
643 {
644 unsigned i;
645 float coord[4];
646 float face_coord[4][2];
647
648 get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord);
649
650 if (src->texture->target == PIPE_TEXTURE_CUBE ||
651 src->texture->target == PIPE_TEXTURE_CUBE_ARRAY) {
652 set_texcoords_in_vertices(coord, &face_coord[0][0], 2);
653 util_map_texcoords2d_onto_cubemap(layer % 6,
654 /* pointer, stride in floats */
655 &face_coord[0][0], 2,
656 &ctx->vertices[0][1][0], 8);
657 } else {
658 set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8);
659 }
660
661 /* Set the layer. */
662 switch (src->texture->target) {
663 case PIPE_TEXTURE_3D:
664 {
665 float r = layer / (float)u_minify(src->texture->depth0,
666 src->u.tex.first_level);
667 for (i = 0; i < 4; i++)
668 ctx->vertices[i][1][2] = r; /*r*/
669 }
670 break;
671
672 case PIPE_TEXTURE_1D_ARRAY:
673 for (i = 0; i < 4; i++)
674 ctx->vertices[i][1][1] = (float) layer; /*t*/
675 break;
676
677 case PIPE_TEXTURE_2D_ARRAY:
678 for (i = 0; i < 4; i++) {
679 ctx->vertices[i][1][2] = (float) layer; /*r*/
680 ctx->vertices[i][1][3] = (float) sample; /*q*/
681 }
682 break;
683
684 case PIPE_TEXTURE_2D:
685 for (i = 0; i < 4; i++) {
686 ctx->vertices[i][1][2] = (float) sample; /*r*/
687 }
688 break;
689
690 default:;
691 }
692 }
693
694 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
695 unsigned width, unsigned height)
696 {
697 ctx->dst_width = width;
698 ctx->dst_height = height;
699 }
700
701 static void *blitter_get_fs_col(struct blitter_context_priv *ctx,
702 unsigned num_cbufs, boolean int_format)
703 {
704 struct pipe_context *pipe = ctx->base.pipe;
705
706 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
707
708 if (int_format) {
709 if (!ctx->fs_col_int[num_cbufs])
710 ctx->fs_col_int[num_cbufs] =
711 util_make_fragment_cloneinput_shader(pipe, num_cbufs,
712 TGSI_SEMANTIC_GENERIC,
713 TGSI_INTERPOLATE_CONSTANT);
714 return ctx->fs_col_int[num_cbufs];
715 } else {
716 if (!ctx->fs_col[num_cbufs])
717 ctx->fs_col[num_cbufs] =
718 util_make_fragment_cloneinput_shader(pipe, num_cbufs,
719 TGSI_SEMANTIC_GENERIC,
720 TGSI_INTERPOLATE_LINEAR);
721 return ctx->fs_col[num_cbufs];
722 }
723 }
724
725 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
726 enum pipe_texture_target target,
727 unsigned nr_samples)
728 {
729 struct pipe_context *pipe = ctx->base.pipe;
730
731 assert(target < PIPE_MAX_TEXTURE_TYPES);
732
733 if (nr_samples > 1) {
734 void **shader = &ctx->fs_texfetch_col_msaa[target];
735
736 /* Create the fragment shader on-demand. */
737 if (!*shader) {
738 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
739 nr_samples);
740
741 *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex);
742 }
743
744 return *shader;
745 } else {
746 void **shader = &ctx->fs_texfetch_col[target];
747
748 /* Create the fragment shader on-demand. */
749 if (!*shader) {
750 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
751
752 *shader =
753 util_make_fragment_tex_shader(pipe, tgsi_tex,
754 TGSI_INTERPOLATE_LINEAR);
755 }
756
757 return *shader;
758 }
759 }
760
761 static INLINE
762 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
763 enum pipe_texture_target target,
764 unsigned nr_samples)
765 {
766 struct pipe_context *pipe = ctx->base.pipe;
767
768 assert(target < PIPE_MAX_TEXTURE_TYPES);
769
770 if (nr_samples > 1) {
771 void **shader = &ctx->fs_texfetch_depth_msaa[target];
772
773 /* Create the fragment shader on-demand. */
774 if (!*shader) {
775 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
776 nr_samples);
777
778 *shader =
779 util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
780 }
781
782 return *shader;
783 } else {
784 void **shader = &ctx->fs_texfetch_depth[target];
785
786 /* Create the fragment shader on-demand. */
787 if (!*shader) {
788 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
789
790 *shader =
791 util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
792 TGSI_INTERPOLATE_LINEAR);
793 }
794
795 return *shader;
796 }
797 }
798
799 static INLINE
800 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
801 enum pipe_texture_target target,
802 unsigned nr_samples)
803 {
804 struct pipe_context *pipe = ctx->base.pipe;
805
806 assert(target < PIPE_MAX_TEXTURE_TYPES);
807
808 if (nr_samples > 1) {
809 void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
810
811 /* Create the fragment shader on-demand. */
812 if (!*shader) {
813 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
814 nr_samples);
815
816 *shader =
817 util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
818 }
819
820 return *shader;
821 } else {
822 void **shader = &ctx->fs_texfetch_depthstencil[target];
823
824 /* Create the fragment shader on-demand. */
825 if (!*shader) {
826 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
827
828 *shader =
829 util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
830 TGSI_INTERPOLATE_LINEAR);
831 }
832
833 return *shader;
834 }
835 }
836
837 static INLINE
838 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
839 enum pipe_texture_target target,
840 unsigned nr_samples)
841 {
842 struct pipe_context *pipe = ctx->base.pipe;
843
844 assert(target < PIPE_MAX_TEXTURE_TYPES);
845
846 if (nr_samples > 1) {
847 void **shader = &ctx->fs_texfetch_stencil_msaa[target];
848
849 /* Create the fragment shader on-demand. */
850 if (!*shader) {
851 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target,
852 nr_samples);
853
854 *shader =
855 util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
856 }
857
858 return *shader;
859 } else {
860 void **shader = &ctx->fs_texfetch_stencil[target];
861
862 /* Create the fragment shader on-demand. */
863 if (!*shader) {
864 unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
865
866 *shader =
867 util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
868 TGSI_INTERPOLATE_LINEAR);
869 }
870
871 return *shader;
872 }
873 }
874
875 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
876 {
877 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
878 struct pipe_screen *screen = blitter->pipe->screen;
879 unsigned num_cbufs, i, target, max_samples;
880 boolean has_arraytex, has_cubearraytex;
881
882 num_cbufs = MAX2(screen->get_param(screen,
883 PIPE_CAP_MAX_RENDER_TARGETS), 1);
884 max_samples = ctx->has_texture_multisample ? 2 : 1;
885 has_arraytex = screen->get_param(screen,
886 PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
887 has_cubearraytex = screen->get_param(screen,
888 PIPE_CAP_CUBE_MAP_ARRAY) != 0;
889
890 for (i = 0; i < num_cbufs; i++) {
891 blitter_get_fs_col(ctx, i, FALSE);
892 blitter_get_fs_col(ctx, i, TRUE);
893 }
894
895 /* It only matters if i <= 1 or > 1. */
896 for (i = 1; i <= max_samples; i++) {
897 for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
898 if (!has_arraytex &&
899 (target == PIPE_TEXTURE_1D_ARRAY ||
900 target == PIPE_TEXTURE_2D_ARRAY)) {
901 continue;
902 }
903 if (!has_cubearraytex &&
904 (target == PIPE_TEXTURE_CUBE_ARRAY))
905 continue;
906
907 blitter_get_fs_texfetch_col(ctx, target, i);
908 blitter_get_fs_texfetch_depth(ctx, target, i);
909 if (ctx->has_stencil_export) {
910 blitter_get_fs_texfetch_depthstencil(ctx, target, i);
911 blitter_get_fs_texfetch_stencil(ctx, target, i);
912 }
913 }
914 }
915 }
916
917 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
918 boolean scissor)
919 {
920 struct pipe_context *pipe = ctx->base.pipe;
921
922 pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor
923 : ctx->rs_state);
924 pipe->bind_vs_state(pipe, ctx->vs);
925 if (ctx->has_geometry_shader)
926 pipe->bind_gs_state(pipe, NULL);
927 if (ctx->has_stream_out)
928 pipe->set_stream_output_targets(pipe, 0, NULL, 0);
929 }
930
931 static void blitter_draw(struct blitter_context_priv *ctx,
932 int x1, int y1, int x2, int y2, float depth)
933 {
934 struct pipe_resource *buf = NULL;
935 unsigned offset = 0;
936
937 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
938
939 u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices,
940 &offset, &buf);
941 u_upload_unmap(ctx->upload);
942 util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, ctx->base.vb_slot,
943 offset, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
944 pipe_resource_reference(&buf, NULL);
945 }
946
947 void util_blitter_draw_rectangle(struct blitter_context *blitter,
948 int x1, int y1, int x2, int y2, float depth,
949 enum blitter_attrib_type type,
950 const union pipe_color_union *attrib)
951 {
952 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
953
954 switch (type) {
955 case UTIL_BLITTER_ATTRIB_COLOR:
956 blitter_set_clear_color(ctx, attrib);
957 break;
958
959 case UTIL_BLITTER_ATTRIB_TEXCOORD:
960 set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8);
961 break;
962
963 default:;
964 }
965
966 blitter_draw(ctx, x1, y1, x2, y2, depth);
967 }
968
969 static void util_blitter_clear_custom(struct blitter_context *blitter,
970 unsigned width, unsigned height,
971 unsigned num_cbufs,
972 unsigned clear_buffers,
973 enum pipe_format cbuf_format,
974 const union pipe_color_union *color,
975 double depth, unsigned stencil,
976 void *custom_blend, void *custom_dsa)
977 {
978 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
979 struct pipe_context *pipe = ctx->base.pipe;
980 struct pipe_stencil_ref sr = { { 0 } };
981 boolean int_format = util_format_is_pure_integer(cbuf_format);
982 assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
983
984 blitter_set_running_flag(ctx);
985 blitter_check_saved_vertex_states(ctx);
986 blitter_check_saved_fragment_states(ctx);
987 blitter_disable_render_cond(ctx);
988
989 /* bind states */
990 if (custom_blend) {
991 pipe->bind_blend_state(pipe, custom_blend);
992 } else if (clear_buffers & PIPE_CLEAR_COLOR) {
993 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
994 } else {
995 pipe->bind_blend_state(pipe, ctx->blend[0]);
996 }
997
998 if (custom_dsa) {
999 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1000 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1001 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1002 } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1003 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1004 } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1005 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1006 } else {
1007 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1008 }
1009
1010 sr.ref_value[0] = stencil & 0xff;
1011 pipe->set_stencil_ref(pipe, &sr);
1012
1013 if (util_format_is_pure_sint(cbuf_format)) {
1014 pipe->bind_vertex_elements_state(pipe, ctx->velem_sint_state);
1015 } else if (util_format_is_pure_uint(cbuf_format)) {
1016 pipe->bind_vertex_elements_state(pipe, ctx->velem_uint_state);
1017 } else {
1018 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1019 }
1020 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs, int_format));
1021 pipe->set_sample_mask(pipe, ~0);
1022
1023 blitter_set_common_draw_rect_state(ctx, FALSE);
1024 blitter_set_dst_dimensions(ctx, width, height);
1025 blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth,
1026 UTIL_BLITTER_ATTRIB_COLOR, color);
1027
1028 blitter_restore_vertex_states(ctx);
1029 blitter_restore_fragment_states(ctx);
1030 blitter_restore_render_cond(ctx);
1031 blitter_unset_running_flag(ctx);
1032 }
1033
1034 void util_blitter_clear(struct blitter_context *blitter,
1035 unsigned width, unsigned height,
1036 unsigned num_cbufs,
1037 unsigned clear_buffers,
1038 enum pipe_format cbuf_format,
1039 const union pipe_color_union *color,
1040 double depth, unsigned stencil)
1041 {
1042 util_blitter_clear_custom(blitter, width, height, num_cbufs,
1043 clear_buffers, cbuf_format, color, depth, stencil,
1044 NULL, NULL);
1045 }
1046
1047 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1048 unsigned width, unsigned height,
1049 double depth, void *custom_dsa)
1050 {
1051 static const union pipe_color_union color;
1052 util_blitter_clear_custom(blitter, width, height, 0,
1053 0, PIPE_FORMAT_NONE, &color, depth, 0, NULL, custom_dsa);
1054 }
1055
1056 static
1057 boolean is_overlap(int dstx, int dsty, int dstz,
1058 const struct pipe_box *srcbox)
1059 {
1060 struct pipe_box src = *srcbox;
1061
1062 if (src.width < 0) {
1063 src.x += src.width;
1064 src.width = -src.width;
1065 }
1066 if (src.height < 0) {
1067 src.y += src.height;
1068 src.height = -src.height;
1069 }
1070 if (src.depth < 0) {
1071 src.z += src.depth;
1072 src.depth = -src.depth;
1073 }
1074 return src.x < dstx+src.width && src.x+src.width > dstx &&
1075 src.y < dsty+src.height && src.y+src.height > dsty &&
1076 src.z < dstz+src.depth && src.z+src.depth > dstz;
1077 }
1078
1079 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1080 struct pipe_resource *dst,
1081 unsigned dstlevel,
1082 unsigned dstz,
1083 const struct pipe_box *srcbox)
1084 {
1085 memset(dst_templ, 0, sizeof(*dst_templ));
1086 dst_templ->format = dst->format;
1087 if (util_format_is_depth_or_stencil(dst->format)) {
1088 dst_templ->usage = PIPE_BIND_DEPTH_STENCIL;
1089 } else {
1090 dst_templ->usage = PIPE_BIND_RENDER_TARGET;
1091 }
1092 dst_templ->format = util_format_linear(dst->format);
1093 dst_templ->u.tex.level = dstlevel;
1094 dst_templ->u.tex.first_layer = dstz;
1095 dst_templ->u.tex.last_layer = dstz + srcbox->depth - 1;
1096 }
1097
1098 void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ,
1099 struct pipe_resource *src,
1100 unsigned srclevel)
1101 {
1102 memset(src_templ, 0, sizeof(*src_templ));
1103 src_templ->format = util_format_linear(src->format);
1104 src_templ->u.tex.first_level = srclevel;
1105 src_templ->u.tex.last_level = srclevel;
1106 src_templ->u.tex.first_layer = 0;
1107 src_templ->u.tex.last_layer =
1108 src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1109 : src->array_size - 1;
1110 src_templ->swizzle_r = PIPE_SWIZZLE_RED;
1111 src_templ->swizzle_g = PIPE_SWIZZLE_GREEN;
1112 src_templ->swizzle_b = PIPE_SWIZZLE_BLUE;
1113 src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA;
1114 }
1115
1116 static boolean is_blit_generic_supported(struct blitter_context *blitter,
1117 const struct pipe_resource *dst,
1118 enum pipe_format dst_format,
1119 const struct pipe_resource *src,
1120 enum pipe_format src_format,
1121 unsigned mask)
1122 {
1123 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1124 struct pipe_screen *screen = ctx->base.pipe->screen;
1125
1126 if (dst) {
1127 unsigned bind;
1128 boolean is_stencil;
1129 const struct util_format_description *desc =
1130 util_format_description(dst_format);
1131
1132 is_stencil = util_format_has_stencil(desc);
1133
1134 /* Stencil export must be supported for stencil copy. */
1135 if ((mask & PIPE_MASK_S) && is_stencil && !ctx->has_stencil_export) {
1136 return FALSE;
1137 }
1138
1139 if (is_stencil || util_format_has_depth(desc))
1140 bind = PIPE_BIND_DEPTH_STENCIL;
1141 else
1142 bind = PIPE_BIND_RENDER_TARGET;
1143
1144 if (!screen->is_format_supported(screen, dst_format, dst->target,
1145 dst->nr_samples, bind)) {
1146 return FALSE;
1147 }
1148 }
1149
1150 if (src) {
1151 if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1152 return FALSE;
1153 }
1154
1155 if (!screen->is_format_supported(screen, src_format, src->target,
1156 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
1157 return FALSE;
1158 }
1159
1160 /* Check stencil sampler support for stencil copy. */
1161 if (util_format_has_stencil(util_format_description(src_format))) {
1162 enum pipe_format stencil_format =
1163 util_format_stencil_only(src_format);
1164 assert(stencil_format != PIPE_FORMAT_NONE);
1165
1166 if (stencil_format != src_format &&
1167 !screen->is_format_supported(screen, stencil_format, src->target,
1168 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
1169 return FALSE;
1170 }
1171 }
1172 }
1173
1174 return TRUE;
1175 }
1176
1177 boolean util_blitter_is_copy_supported(struct blitter_context *blitter,
1178 const struct pipe_resource *dst,
1179 const struct pipe_resource *src,
1180 unsigned mask)
1181 {
1182 return is_blit_generic_supported(blitter, dst, dst->format,
1183 src, src->format, mask);
1184 }
1185
1186 boolean util_blitter_is_blit_supported(struct blitter_context *blitter,
1187 const struct pipe_blit_info *info)
1188 {
1189 return is_blit_generic_supported(blitter,
1190 info->dst.resource, info->dst.format,
1191 info->src.resource, info->src.format,
1192 info->mask);
1193 }
1194
1195 void util_blitter_copy_texture(struct blitter_context *blitter,
1196 struct pipe_resource *dst,
1197 unsigned dst_level,
1198 unsigned dstx, unsigned dsty, unsigned dstz,
1199 struct pipe_resource *src,
1200 unsigned src_level,
1201 const struct pipe_box *srcbox, unsigned mask,
1202 boolean copy_all_samples)
1203 {
1204 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1205 struct pipe_context *pipe = ctx->base.pipe;
1206 struct pipe_surface *dst_view, dst_templ;
1207 struct pipe_sampler_view src_templ, *src_view;
1208
1209 assert(dst && src);
1210 assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1211
1212 /* Initialize the surface. */
1213 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz, srcbox);
1214 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1215
1216 /* Initialize the sampler view. */
1217 util_blitter_default_src_texture(&src_templ, src, src_level);
1218 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1219
1220 /* Copy. */
1221 util_blitter_blit_generic(blitter, dst_view, dstx, dsty,
1222 abs(srcbox->width), abs(srcbox->height),
1223 src_view, srcbox, src->width0, src->height0,
1224 mask, PIPE_TEX_FILTER_NEAREST, NULL,
1225 copy_all_samples);
1226
1227 pipe_surface_reference(&dst_view, NULL);
1228 pipe_sampler_view_reference(&src_view, NULL);
1229 }
1230
1231 void util_blitter_blit_generic(struct blitter_context *blitter,
1232 struct pipe_surface *dst,
1233 int dstx, int dsty,
1234 unsigned dst_width, unsigned dst_height,
1235 struct pipe_sampler_view *src,
1236 const struct pipe_box *srcbox,
1237 unsigned src_width0, unsigned src_height0,
1238 unsigned mask, unsigned filter,
1239 const struct pipe_scissor_state *scissor,
1240 boolean copy_all_samples)
1241 {
1242 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1243 struct pipe_context *pipe = ctx->base.pipe;
1244 struct pipe_framebuffer_state fb_state;
1245 enum pipe_texture_target src_target = src->texture->target;
1246 boolean has_depth, has_stencil, has_color;
1247 boolean blit_stencil, blit_depth, blit_color;
1248 void *sampler_state;
1249 const struct util_format_description *src_desc =
1250 util_format_description(src->format);
1251 const struct util_format_description *dst_desc =
1252 util_format_description(dst->format);
1253
1254 has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
1255 dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1256 has_depth = util_format_has_depth(src_desc) &&
1257 util_format_has_depth(dst_desc);
1258 has_stencil = util_format_has_stencil(src_desc) &&
1259 util_format_has_stencil(dst_desc);
1260
1261 blit_color = has_color && (mask & PIPE_MASK_RGBA);
1262 blit_depth = has_depth && (mask & PIPE_MASK_Z);
1263 blit_stencil = has_stencil && (mask & PIPE_MASK_S) &&
1264 ctx->has_stencil_export;
1265
1266 if (!blit_stencil && !blit_depth && !blit_color) {
1267 return;
1268 }
1269
1270 /* Sanity checks. */
1271 if (dst->texture == src->texture &&
1272 dst->u.tex.level == src->u.tex.first_level) {
1273 assert(!is_overlap(dstx, dsty, 0, srcbox));
1274 }
1275 /* XXX should handle 3d regions */
1276 assert(srcbox->depth == 1);
1277
1278 /* Check whether the states are properly saved. */
1279 blitter_set_running_flag(ctx);
1280 blitter_check_saved_vertex_states(ctx);
1281 blitter_check_saved_fragment_states(ctx);
1282 blitter_check_saved_textures(ctx);
1283 blitter_check_saved_fb_state(ctx);
1284 blitter_disable_render_cond(ctx);
1285
1286 /* Initialize framebuffer state. */
1287 fb_state.width = dst->width;
1288 fb_state.height = dst->height;
1289
1290 if (blit_depth || blit_stencil) {
1291 pipe->bind_blend_state(pipe, ctx->blend[0]);
1292
1293 if (blit_depth && blit_stencil) {
1294 pipe->bind_depth_stencil_alpha_state(pipe,
1295 ctx->dsa_write_depth_stencil);
1296 ctx->bind_fs_state(pipe,
1297 blitter_get_fs_texfetch_depthstencil(ctx, src->texture->target,
1298 src->texture->nr_samples));
1299 } else if (blit_depth) {
1300 pipe->bind_depth_stencil_alpha_state(pipe,
1301 ctx->dsa_write_depth_keep_stencil);
1302 ctx->bind_fs_state(pipe,
1303 blitter_get_fs_texfetch_depth(ctx, src->texture->target,
1304 src->texture->nr_samples));
1305 } else { /* is_stencil */
1306 pipe->bind_depth_stencil_alpha_state(pipe,
1307 ctx->dsa_keep_depth_write_stencil);
1308 ctx->bind_fs_state(pipe,
1309 blitter_get_fs_texfetch_stencil(ctx, src->texture->target,
1310 src->texture->nr_samples));
1311 }
1312
1313 fb_state.nr_cbufs = 0;
1314 fb_state.zsbuf = dst;
1315 } else {
1316 pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]);
1317 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1318 ctx->bind_fs_state(pipe,
1319 blitter_get_fs_texfetch_col(ctx, src->texture->target,
1320 src->texture->nr_samples));
1321
1322 fb_state.nr_cbufs = 1;
1323 fb_state.cbufs[0] = dst;
1324 fb_state.zsbuf = 0;
1325 }
1326
1327 /* Set the linear filter only for scaled color non-MSAA blits. */
1328 if (filter == PIPE_TEX_FILTER_LINEAR &&
1329 !blit_depth && !blit_stencil &&
1330 src->texture->nr_samples <= 1 &&
1331 (dst_width != abs(srcbox->width) || dst_height != abs(srcbox->height))) {
1332 sampler_state = ctx->sampler_state_linear;
1333 } else {
1334 sampler_state = ctx->sampler_state;
1335 }
1336
1337 /* Set samplers. */
1338 if (blit_depth && blit_stencil) {
1339 /* Setup two samplers, one for depth and the other one for stencil. */
1340 struct pipe_sampler_view templ;
1341 struct pipe_sampler_view *views[2];
1342 void *samplers[2] = {sampler_state, sampler_state};
1343
1344 templ = *src;
1345 templ.format = util_format_stencil_only(templ.format);
1346 assert(templ.format != PIPE_FORMAT_NONE);
1347
1348 views[0] = src;
1349 views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
1350
1351 pipe->set_fragment_sampler_views(pipe, 2, views);
1352 pipe->bind_fragment_sampler_states(pipe, 2, samplers);
1353
1354 pipe_sampler_view_reference(&views[1], NULL);
1355 } else if (blit_stencil) {
1356 /* Set a stencil-only sampler view for it not to sample depth instead. */
1357 struct pipe_sampler_view templ;
1358 struct pipe_sampler_view *view;
1359
1360 templ = *src;
1361 templ.format = util_format_stencil_only(templ.format);
1362 assert(templ.format != PIPE_FORMAT_NONE);
1363
1364 view = pipe->create_sampler_view(pipe, src->texture, &templ);
1365
1366 pipe->set_fragment_sampler_views(pipe, 1, &view);
1367 pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
1368
1369 pipe_sampler_view_reference(&view, NULL);
1370 } else {
1371 pipe->set_fragment_sampler_views(pipe, 1, &src);
1372 pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state);
1373 }
1374
1375 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1376 pipe->set_framebuffer_state(pipe, &fb_state);
1377
1378 if (scissor) {
1379 pipe->set_scissor_state(pipe, scissor);
1380 }
1381
1382 blitter_set_common_draw_rect_state(ctx, scissor != NULL);
1383 blitter_set_dst_dimensions(ctx, dst->width, dst->height);
1384
1385 if ((src_target == PIPE_TEXTURE_1D ||
1386 src_target == PIPE_TEXTURE_2D ||
1387 src_target == PIPE_TEXTURE_RECT) &&
1388 src->texture->nr_samples <= 1) {
1389 /* Draw the quad with the draw_rectangle callback. */
1390
1391 /* Set texture coordinates. - use a pipe color union
1392 * for interface purposes.
1393 * XXX pipe_color_union is a wrong name since we use that to set
1394 * texture coordinates too.
1395 */
1396 union pipe_color_union coord;
1397 get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y,
1398 srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f);
1399
1400 /* Draw. */
1401 pipe->set_sample_mask(pipe, ~0);
1402 blitter->draw_rectangle(blitter, dstx, dsty,
1403 dstx+dst_width, dsty+dst_height, 0,
1404 UTIL_BLITTER_ATTRIB_TEXCOORD, &coord);
1405 } else {
1406 /* Draw the quad with the generic codepath. */
1407 if (copy_all_samples &&
1408 src->texture->nr_samples == dst->texture->nr_samples &&
1409 dst->texture->nr_samples > 1) {
1410 /* MSAA copy. */
1411 unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1;
1412
1413 for (i = 0; i <= max_sample; i++) {
1414 pipe->set_sample_mask(pipe, 1 << i);
1415 blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z,
1416 i, srcbox->x, srcbox->y,
1417 srcbox->x + srcbox->width,
1418 srcbox->y + srcbox->height);
1419 blitter_draw(ctx, dstx, dsty,
1420 dstx+dst_width, dsty+dst_height, 0);
1421 }
1422 } else {
1423 pipe->set_sample_mask(pipe, ~0);
1424 blitter_set_texcoords(ctx, src, src_width0, src_height0, srcbox->z, 0,
1425 srcbox->x, srcbox->y,
1426 srcbox->x + srcbox->width,
1427 srcbox->y + srcbox->height);
1428 blitter_draw(ctx, dstx, dsty, dstx+dst_width, dsty+dst_height, 0);
1429 }
1430 }
1431
1432 blitter_restore_vertex_states(ctx);
1433 blitter_restore_fragment_states(ctx);
1434 blitter_restore_textures(ctx);
1435 blitter_restore_fb_state(ctx);
1436 if (scissor) {
1437 pipe->set_scissor_state(pipe, &ctx->base.saved_scissor);
1438 }
1439 blitter_restore_render_cond(ctx);
1440 blitter_unset_running_flag(ctx);
1441 }
1442
1443 void
1444 util_blitter_blit(struct blitter_context *blitter,
1445 const struct pipe_blit_info *info)
1446 {
1447 struct pipe_resource *dst = info->dst.resource;
1448 struct pipe_resource *src = info->src.resource;
1449 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1450 struct pipe_context *pipe = ctx->base.pipe;
1451 struct pipe_surface *dst_view, dst_templ;
1452 struct pipe_sampler_view src_templ, *src_view;
1453
1454 /* Initialize the surface. */
1455 util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
1456 info->dst.box.z, &info->src.box);
1457 dst_templ.format = info->dst.format;
1458 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1459
1460 /* Initialize the sampler view. */
1461 util_blitter_default_src_texture(&src_templ, src, info->src.level);
1462 src_templ.format = info->src.format;
1463 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1464
1465 /* Copy. */
1466 util_blitter_blit_generic(blitter, dst_view,
1467 info->dst.box.x, info->dst.box.y,
1468 info->dst.box.width, info->dst.box.height,
1469 src_view, &info->src.box, src->width0, src->height0,
1470 info->mask, info->filter,
1471 info->scissor_enable ? &info->scissor : NULL, TRUE);
1472
1473 pipe_surface_reference(&dst_view, NULL);
1474 pipe_sampler_view_reference(&src_view, NULL);
1475 }
1476
1477 /* Clear a region of a color surface to a constant value. */
1478 void util_blitter_clear_render_target(struct blitter_context *blitter,
1479 struct pipe_surface *dstsurf,
1480 const union pipe_color_union *color,
1481 unsigned dstx, unsigned dsty,
1482 unsigned width, unsigned height)
1483 {
1484 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1485 struct pipe_context *pipe = ctx->base.pipe;
1486 struct pipe_framebuffer_state fb_state;
1487
1488 assert(dstsurf->texture);
1489 if (!dstsurf->texture)
1490 return;
1491
1492 /* check the saved state */
1493 blitter_set_running_flag(ctx);
1494 blitter_check_saved_vertex_states(ctx);
1495 blitter_check_saved_fragment_states(ctx);
1496 blitter_check_saved_fb_state(ctx);
1497 blitter_disable_render_cond(ctx);
1498
1499 /* bind states */
1500 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]);
1501 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1502 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
1503 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1504
1505 /* set a framebuffer state */
1506 fb_state.width = dstsurf->width;
1507 fb_state.height = dstsurf->height;
1508 fb_state.nr_cbufs = 1;
1509 fb_state.cbufs[0] = dstsurf;
1510 fb_state.zsbuf = 0;
1511 pipe->set_framebuffer_state(pipe, &fb_state);
1512 pipe->set_sample_mask(pipe, ~0);
1513
1514 blitter_set_common_draw_rect_state(ctx, FALSE);
1515 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1516 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0,
1517 UTIL_BLITTER_ATTRIB_COLOR, color);
1518
1519 blitter_restore_vertex_states(ctx);
1520 blitter_restore_fragment_states(ctx);
1521 blitter_restore_fb_state(ctx);
1522 blitter_restore_render_cond(ctx);
1523 blitter_unset_running_flag(ctx);
1524 }
1525
1526 /* Clear a region of a depth stencil surface. */
1527 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
1528 struct pipe_surface *dstsurf,
1529 unsigned clear_flags,
1530 double depth,
1531 unsigned stencil,
1532 unsigned dstx, unsigned dsty,
1533 unsigned width, unsigned height)
1534 {
1535 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1536 struct pipe_context *pipe = ctx->base.pipe;
1537 struct pipe_framebuffer_state fb_state;
1538 struct pipe_stencil_ref sr = { { 0 } };
1539
1540 assert(dstsurf->texture);
1541 if (!dstsurf->texture)
1542 return;
1543
1544 /* check the saved state */
1545 blitter_set_running_flag(ctx);
1546 blitter_check_saved_vertex_states(ctx);
1547 blitter_check_saved_fragment_states(ctx);
1548 blitter_check_saved_fb_state(ctx);
1549 blitter_disable_render_cond(ctx);
1550
1551 /* bind states */
1552 pipe->bind_blend_state(pipe, ctx->blend[0]);
1553 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1554 sr.ref_value[0] = stencil & 0xff;
1555 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1556 pipe->set_stencil_ref(pipe, &sr);
1557 }
1558 else if (clear_flags & PIPE_CLEAR_DEPTH) {
1559 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1560 }
1561 else if (clear_flags & PIPE_CLEAR_STENCIL) {
1562 sr.ref_value[0] = stencil & 0xff;
1563 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1564 pipe->set_stencil_ref(pipe, &sr);
1565 }
1566 else
1567 /* hmm that should be illegal probably, or make it a no-op somewhere */
1568 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1569
1570 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
1571 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1572
1573 /* set a framebuffer state */
1574 fb_state.width = dstsurf->width;
1575 fb_state.height = dstsurf->height;
1576 fb_state.nr_cbufs = 0;
1577 fb_state.cbufs[0] = 0;
1578 fb_state.zsbuf = dstsurf;
1579 pipe->set_framebuffer_state(pipe, &fb_state);
1580 pipe->set_sample_mask(pipe, ~0);
1581
1582 blitter_set_common_draw_rect_state(ctx, FALSE);
1583 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1584 blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height,
1585 (float) depth,
1586 UTIL_BLITTER_ATTRIB_NONE, NULL);
1587
1588 blitter_restore_vertex_states(ctx);
1589 blitter_restore_fragment_states(ctx);
1590 blitter_restore_fb_state(ctx);
1591 blitter_restore_render_cond(ctx);
1592 blitter_unset_running_flag(ctx);
1593 }
1594
1595 /* draw a rectangle across a region using a custom dsa stage - for r600g */
1596 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
1597 struct pipe_surface *zsurf,
1598 struct pipe_surface *cbsurf,
1599 unsigned sample_mask,
1600 void *dsa_stage, float depth)
1601 {
1602 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1603 struct pipe_context *pipe = ctx->base.pipe;
1604 struct pipe_framebuffer_state fb_state;
1605
1606 assert(zsurf->texture);
1607 if (!zsurf->texture)
1608 return;
1609
1610 /* check the saved state */
1611 blitter_set_running_flag(ctx);
1612 blitter_check_saved_vertex_states(ctx);
1613 blitter_check_saved_fragment_states(ctx);
1614 blitter_check_saved_fb_state(ctx);
1615 blitter_disable_render_cond(ctx);
1616
1617 /* bind states */
1618 pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA] :
1619 ctx->blend[0]);
1620 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
1621 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 0, FALSE));
1622 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1623
1624 /* set a framebuffer state */
1625 fb_state.width = zsurf->width;
1626 fb_state.height = zsurf->height;
1627 fb_state.nr_cbufs = 1;
1628 if (cbsurf) {
1629 fb_state.cbufs[0] = cbsurf;
1630 fb_state.nr_cbufs = 1;
1631 } else {
1632 fb_state.cbufs[0] = NULL;
1633 fb_state.nr_cbufs = 0;
1634 }
1635 fb_state.zsbuf = zsurf;
1636 pipe->set_framebuffer_state(pipe, &fb_state);
1637 pipe->set_sample_mask(pipe, sample_mask);
1638
1639 blitter_set_common_draw_rect_state(ctx, FALSE);
1640 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
1641 blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth,
1642 UTIL_BLITTER_ATTRIB_NONE, NULL);
1643
1644 blitter_restore_vertex_states(ctx);
1645 blitter_restore_fragment_states(ctx);
1646 blitter_restore_fb_state(ctx);
1647 blitter_restore_render_cond(ctx);
1648 blitter_unset_running_flag(ctx);
1649 }
1650
1651 void util_blitter_copy_buffer(struct blitter_context *blitter,
1652 struct pipe_resource *dst,
1653 unsigned dstx,
1654 struct pipe_resource *src,
1655 unsigned srcx,
1656 unsigned size)
1657 {
1658 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1659 struct pipe_context *pipe = ctx->base.pipe;
1660 struct pipe_vertex_buffer vb;
1661 struct pipe_stream_output_target *so_target;
1662
1663 if (srcx >= src->width0 ||
1664 dstx >= dst->width0) {
1665 return;
1666 }
1667 if (srcx + size > src->width0) {
1668 size = src->width0 - srcx;
1669 }
1670 if (dstx + size > dst->width0) {
1671 size = dst->width0 - dstx;
1672 }
1673
1674 /* Drivers not capable of Stream Out should not call this function
1675 * in the first place. */
1676 assert(ctx->has_stream_out);
1677
1678 /* Some alignment is required. */
1679 if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
1680 !ctx->has_stream_out) {
1681 struct pipe_box box;
1682 u_box_1d(srcx, size, &box);
1683 util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
1684 return;
1685 }
1686
1687 blitter_set_running_flag(ctx);
1688 blitter_check_saved_vertex_states(ctx);
1689 blitter_disable_render_cond(ctx);
1690
1691 vb.buffer = src;
1692 vb.buffer_offset = srcx;
1693 vb.stride = 4;
1694
1695 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1696 pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf);
1697 pipe->bind_vs_state(pipe, ctx->vs_pos_only);
1698 if (ctx->has_geometry_shader)
1699 pipe->bind_gs_state(pipe, NULL);
1700 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
1701
1702 so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
1703 pipe->set_stream_output_targets(pipe, 1, &so_target, 0);
1704
1705 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
1706
1707 blitter_restore_vertex_states(ctx);
1708 blitter_restore_render_cond(ctx);
1709 blitter_unset_running_flag(ctx);
1710 pipe_so_target_reference(&so_target, NULL);
1711 }
1712
1713 /* probably radeon specific */
1714 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
1715 struct pipe_resource *dst,
1716 unsigned dst_level,
1717 unsigned dst_layer,
1718 struct pipe_resource *src,
1719 unsigned src_layer,
1720 unsigned sample_mask,
1721 void *custom_blend,
1722 enum pipe_format format)
1723 {
1724 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1725 struct pipe_context *pipe = ctx->base.pipe;
1726 struct pipe_framebuffer_state fb_state;
1727 struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
1728
1729 blitter_set_running_flag(ctx);
1730 blitter_check_saved_vertex_states(ctx);
1731 blitter_check_saved_fragment_states(ctx);
1732 blitter_disable_render_cond(ctx);
1733
1734 /* bind states */
1735 pipe->bind_blend_state(pipe, custom_blend);
1736 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1737 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1738 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
1739 pipe->set_sample_mask(pipe, sample_mask);
1740
1741 memset(&surf_tmpl, 0, sizeof(surf_tmpl));
1742 surf_tmpl.format = format;
1743 surf_tmpl.u.tex.level = dst_level;
1744 surf_tmpl.u.tex.first_layer = dst_layer;
1745 surf_tmpl.u.tex.last_layer = dst_layer;
1746 surf_tmpl.usage = PIPE_BIND_RENDER_TARGET;
1747
1748 dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
1749
1750 surf_tmpl.u.tex.level = 0;
1751 surf_tmpl.u.tex.first_layer = src_layer;
1752 surf_tmpl.u.tex.last_layer = src_layer;
1753
1754 srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
1755
1756 /* set a framebuffer state */
1757 fb_state.width = src->width0;
1758 fb_state.height = src->height0;
1759 fb_state.nr_cbufs = 2;
1760 fb_state.cbufs[0] = srcsurf;
1761 fb_state.cbufs[1] = dstsurf;
1762 fb_state.zsbuf = NULL;
1763 pipe->set_framebuffer_state(pipe, &fb_state);
1764
1765 blitter_set_common_draw_rect_state(ctx, FALSE);
1766 blitter_set_dst_dimensions(ctx, src->width0, src->height0);
1767 blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0,
1768 0, 0, NULL);
1769 blitter_restore_fb_state(ctx);
1770 blitter_restore_vertex_states(ctx);
1771 blitter_restore_fragment_states(ctx);
1772 blitter_restore_render_cond(ctx);
1773 blitter_unset_running_flag(ctx);
1774
1775 pipe_surface_reference(&srcsurf, NULL);
1776 pipe_surface_reference(&dstsurf, NULL);
1777 }
1778
1779 void util_blitter_custom_color(struct blitter_context *blitter,
1780 struct pipe_surface *dstsurf,
1781 void *custom_blend)
1782 {
1783 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1784 struct pipe_context *pipe = ctx->base.pipe;
1785 struct pipe_framebuffer_state fb_state;
1786
1787 assert(dstsurf->texture);
1788 if (!dstsurf->texture)
1789 return;
1790
1791 /* check the saved state */
1792 blitter_set_running_flag(ctx);
1793 blitter_check_saved_vertex_states(ctx);
1794 blitter_check_saved_fragment_states(ctx);
1795 blitter_check_saved_fb_state(ctx);
1796 blitter_disable_render_cond(ctx);
1797
1798 /* bind states */
1799 pipe->bind_blend_state(pipe, custom_blend);
1800 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1801 ctx->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1, FALSE));
1802 pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
1803 pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
1804
1805 /* set a framebuffer state */
1806 fb_state.width = dstsurf->width;
1807 fb_state.height = dstsurf->height;
1808 fb_state.nr_cbufs = 1;
1809 fb_state.cbufs[0] = dstsurf;
1810 fb_state.zsbuf = 0;
1811 pipe->set_framebuffer_state(pipe, &fb_state);
1812 pipe->set_sample_mask(pipe, ~0);
1813
1814 blitter_set_common_draw_rect_state(ctx, FALSE);
1815 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
1816 blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height,
1817 0, 0, NULL);
1818
1819 blitter_restore_vertex_states(ctx);
1820 blitter_restore_fragment_states(ctx);
1821 blitter_restore_fb_state(ctx);
1822 blitter_restore_render_cond(ctx);
1823 blitter_unset_running_flag(ctx);
1824 }
1825
1826 /* Return whether this is an RGBA, Z, S, or combined ZS format.
1827 */
1828 static unsigned get_format_mask(enum pipe_format format)
1829 {
1830 const struct util_format_description *desc = util_format_description(format);
1831
1832 assert(desc);
1833
1834 if (util_format_has_depth(desc)) {
1835 if (util_format_has_stencil(desc)) {
1836 return PIPE_MASK_ZS;
1837 } else {
1838 return PIPE_MASK_Z;
1839 }
1840 } else {
1841 if (util_format_has_stencil(desc)) {
1842 return PIPE_MASK_S;
1843 } else {
1844 return PIPE_MASK_RGBA;
1845 }
1846 }
1847 }
1848
1849 /* Return if the box is totally inside the resource.
1850 */
1851 static boolean is_box_inside_resource(const struct pipe_resource *res,
1852 const struct pipe_box *box,
1853 unsigned level)
1854 {
1855 unsigned width = 1, height = 1, depth = 1;
1856
1857 switch (res->target) {
1858 case PIPE_BUFFER:
1859 width = res->width0;
1860 height = 1;
1861 depth = 1;
1862 break;
1863 case PIPE_TEXTURE_1D:
1864 width = u_minify(res->width0, level);
1865 height = 1;
1866 depth = 1;
1867 break;
1868 case PIPE_TEXTURE_2D:
1869 case PIPE_TEXTURE_RECT:
1870 width = u_minify(res->width0, level);
1871 height = u_minify(res->height0, level);
1872 depth = 1;
1873 break;
1874 case PIPE_TEXTURE_3D:
1875 width = u_minify(res->width0, level);
1876 height = u_minify(res->height0, level);
1877 depth = u_minify(res->depth0, level);
1878 break;
1879 case PIPE_TEXTURE_CUBE:
1880 width = u_minify(res->width0, level);
1881 height = u_minify(res->height0, level);
1882 depth = 6;
1883 break;
1884 case PIPE_TEXTURE_1D_ARRAY:
1885 width = u_minify(res->width0, level);
1886 height = 1;
1887 depth = res->array_size;
1888 break;
1889 case PIPE_TEXTURE_2D_ARRAY:
1890 width = u_minify(res->width0, level);
1891 height = u_minify(res->height0, level);
1892 depth = res->array_size;
1893 break;
1894 case PIPE_TEXTURE_CUBE_ARRAY:
1895 width = u_minify(res->width0, level);
1896 height = u_minify(res->height0, level);
1897 depth = res->array_size;
1898 assert(res->array_size % 6 == 0);
1899 break;
1900 case PIPE_MAX_TEXTURE_TYPES:;
1901 }
1902
1903 return box->x >= 0 &&
1904 box->x + box->width <= (int) width &&
1905 box->y >= 0 &&
1906 box->y + box->height <= (int) height &&
1907 box->z >= 0 &&
1908 box->z + box->depth <= (int) depth;
1909 }
1910
1911 static unsigned get_sample_count(const struct pipe_resource *res)
1912 {
1913 return res->nr_samples ? res->nr_samples : 1;
1914 }
1915
1916 boolean util_try_blit_via_copy_region(struct pipe_context *ctx,
1917 const struct pipe_blit_info *blit)
1918 {
1919 unsigned mask = get_format_mask(blit->dst.format);
1920
1921 /* No format conversions. */
1922 if (blit->src.resource->format != blit->src.format ||
1923 blit->dst.resource->format != blit->dst.format ||
1924 !util_is_format_compatible(
1925 util_format_description(blit->src.resource->format),
1926 util_format_description(blit->dst.resource->format))) {
1927 return FALSE;
1928 }
1929
1930 /* No masks, no filtering, no scissor. */
1931 if ((blit->mask & mask) != mask ||
1932 blit->filter != PIPE_TEX_FILTER_NEAREST ||
1933 blit->scissor_enable) {
1934 return FALSE;
1935 }
1936
1937 /* No flipping. */
1938 if (blit->src.box.width < 0 ||
1939 blit->src.box.height < 0 ||
1940 blit->src.box.depth < 0) {
1941 return FALSE;
1942 }
1943
1944 /* No scaling. */
1945 if (blit->src.box.width != blit->dst.box.width ||
1946 blit->src.box.height != blit->dst.box.height ||
1947 blit->src.box.depth != blit->dst.box.depth) {
1948 return FALSE;
1949 }
1950
1951 /* No out-of-bounds access. */
1952 if (!is_box_inside_resource(blit->src.resource, &blit->src.box,
1953 blit->src.level) ||
1954 !is_box_inside_resource(blit->dst.resource, &blit->dst.box,
1955 blit->dst.level)) {
1956 return FALSE;
1957 }
1958
1959 /* Sample counts must match. */
1960 if (get_sample_count(blit->src.resource) !=
1961 get_sample_count(blit->dst.resource)) {
1962 return FALSE;
1963 }
1964
1965 ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level,
1966 blit->dst.box.x, blit->dst.box.y, blit->dst.box.z,
1967 blit->src.resource, blit->src.level,
1968 &blit->src.box);
1969 return TRUE;
1970 }