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