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