eadb76a109fbf7cf6d90c5f3b97b44ed16d800b5
[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 VMWARE 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 #define GET_CLEAR_BLEND_STATE_IDX(clear_buffers) \
55 ((clear_buffers) / PIPE_CLEAR_COLOR0)
56
57 #define NUM_RESOLVE_FRAG_SHADERS 5 /* MSAA 2x, 4x, 8x, 16x, 32x */
58 #define GET_MSAA_RESOLVE_FS_IDX(nr_samples) (util_logbase2(nr_samples)-1)
59
60 struct blitter_context_priv
61 {
62 struct blitter_context base;
63
64 float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
65
66 /* Templates for various state objects. */
67
68 /* Constant state objects. */
69 /* Vertex shaders. */
70 void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/
71 void *vs_nogeneric;
72 void *vs_pos_only[4]; /**< Vertex shader which passes pos to the output
73 for clear_buffer/copy_buffer.*/
74 void *vs_layered; /**< Vertex shader which sets LAYER = INSTANCEID. */
75
76 /* Fragment shaders. */
77 void *fs_empty;
78 void *fs_write_one_cbuf;
79 void *fs_write_all_cbufs;
80
81 /* FS which outputs a color from a texture where
82 * the 1st index indicates the texture type / destination type,
83 * the 2nd index is the PIPE_TEXTURE_* to be sampled,
84 * the 3rd index is 0 = use TEX, 1 = use TXF.
85 */
86 void *fs_texfetch_col[5][PIPE_MAX_TEXTURE_TYPES][2];
87
88 /* FS which outputs a depth from a texture, where
89 * the 1st index is the PIPE_TEXTURE_* to be sampled,
90 * the 2nd index is 0 = use TEX, 1 = use TXF.
91 */
92 void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES][2];
93 void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES][2];
94 void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES][2];
95
96 /* FS which outputs one sample from a multisample texture. */
97 void *fs_texfetch_col_msaa[5][PIPE_MAX_TEXTURE_TYPES];
98 void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES];
99 void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES];
100 void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES];
101
102 /* FS which outputs an average of all samples. */
103 void *fs_resolve[PIPE_MAX_TEXTURE_TYPES][NUM_RESOLVE_FRAG_SHADERS][2];
104
105 /* Blend state. */
106 void *blend[PIPE_MASK_RGBA+1][2]; /**< blend state with writemask */
107 void *blend_clear[GET_CLEAR_BLEND_STATE_IDX(PIPE_CLEAR_COLOR)+1];
108
109 /* Depth stencil alpha state. */
110 void *dsa_write_depth_stencil;
111 void *dsa_write_depth_keep_stencil;
112 void *dsa_keep_depth_stencil;
113 void *dsa_keep_depth_write_stencil;
114
115 /* Vertex elements states. */
116 void *velem_state;
117 void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */
118
119 /* Sampler state. */
120 void *sampler_state;
121 void *sampler_state_linear;
122 void *sampler_state_rect;
123 void *sampler_state_rect_linear;
124
125 /* Rasterizer state. */
126 void *rs_state, *rs_state_scissor, *rs_discard_state;
127
128 /* Destination surface dimensions. */
129 unsigned dst_width;
130 unsigned dst_height;
131
132 void *custom_vs;
133
134 bool has_geometry_shader;
135 bool has_tessellation;
136 bool has_layered;
137 bool has_stream_out;
138 bool has_stencil_export;
139 bool has_texture_multisample;
140 bool has_tex_lz;
141 bool has_txf;
142 bool cube_as_2darray;
143 bool cached_all_shaders;
144
145 /* The Draw module overrides these functions.
146 * Always create the blitter before Draw. */
147 void (*bind_fs_state)(struct pipe_context *, void *);
148 void (*delete_fs_state)(struct pipe_context *, void *);
149 };
150
151 struct blitter_context *util_blitter_create(struct pipe_context *pipe)
152 {
153 struct blitter_context_priv *ctx;
154 struct pipe_blend_state blend;
155 struct pipe_depth_stencil_alpha_state dsa;
156 struct pipe_rasterizer_state rs_state;
157 struct pipe_sampler_state sampler_state;
158 struct pipe_vertex_element velem[2];
159 unsigned i, j;
160
161 ctx = CALLOC_STRUCT(blitter_context_priv);
162 if (!ctx)
163 return NULL;
164
165 ctx->base.pipe = pipe;
166 ctx->base.draw_rectangle = util_blitter_draw_rectangle;
167
168 ctx->bind_fs_state = pipe->bind_fs_state;
169 ctx->delete_fs_state = pipe->delete_fs_state;
170
171 /* init state objects for them to be considered invalid */
172 ctx->base.saved_blend_state = INVALID_PTR;
173 ctx->base.saved_dsa_state = INVALID_PTR;
174 ctx->base.saved_rs_state = INVALID_PTR;
175 ctx->base.saved_fs = INVALID_PTR;
176 ctx->base.saved_vs = INVALID_PTR;
177 ctx->base.saved_gs = INVALID_PTR;
178 ctx->base.saved_velem_state = INVALID_PTR;
179 ctx->base.saved_fb_state.nr_cbufs = ~0;
180 ctx->base.saved_num_sampler_views = ~0;
181 ctx->base.saved_num_sampler_states = ~0;
182 ctx->base.saved_num_so_targets = ~0;
183
184 ctx->has_geometry_shader =
185 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY,
186 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
187
188 ctx->has_tessellation =
189 pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_TESS_CTRL,
190 PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0;
191
192 ctx->has_stream_out =
193 pipe->screen->get_param(pipe->screen,
194 PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0;
195
196 ctx->has_stencil_export =
197 pipe->screen->get_param(pipe->screen,
198 PIPE_CAP_SHADER_STENCIL_EXPORT);
199
200 ctx->has_texture_multisample =
201 pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE);
202
203 ctx->has_tex_lz = pipe->screen->get_param(pipe->screen,
204 PIPE_CAP_TGSI_TEX_TXF_LZ);
205 ctx->has_txf = pipe->screen->get_param(pipe->screen,
206 PIPE_CAP_GLSL_FEATURE_LEVEL) > 130;
207 ctx->cube_as_2darray = pipe->screen->get_param(pipe->screen,
208 PIPE_CAP_SAMPLER_VIEW_TARGET);
209
210 /* blend state objects */
211 memset(&blend, 0, sizeof(blend));
212
213 for (i = 0; i <= PIPE_MASK_RGBA; i++) {
214 for (j = 0; j < 2; j++) {
215 memset(&blend.rt[0], 0, sizeof(blend.rt[0]));
216 blend.rt[0].colormask = i;
217 if (j) {
218 blend.rt[0].blend_enable = 1;
219 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
220 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
221 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
222 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
223 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
224 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
225 }
226 ctx->blend[i][j] = pipe->create_blend_state(pipe, &blend);
227 }
228 }
229
230 /* depth stencil alpha state objects */
231 memset(&dsa, 0, sizeof(dsa));
232 ctx->dsa_keep_depth_stencil =
233 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
234
235 dsa.depth.enabled = 1;
236 dsa.depth.writemask = 1;
237 dsa.depth.func = PIPE_FUNC_ALWAYS;
238 ctx->dsa_write_depth_keep_stencil =
239 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
240
241 dsa.stencil[0].enabled = 1;
242 dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
243 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
244 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
245 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
246 dsa.stencil[0].valuemask = 0xff;
247 dsa.stencil[0].writemask = 0xff;
248 ctx->dsa_write_depth_stencil =
249 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
250
251 dsa.depth.enabled = 0;
252 dsa.depth.writemask = 0;
253 ctx->dsa_keep_depth_write_stencil =
254 pipe->create_depth_stencil_alpha_state(pipe, &dsa);
255
256 /* sampler state */
257 memset(&sampler_state, 0, sizeof(sampler_state));
258 sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
259 sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
260 sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
261 sampler_state.normalized_coords = 1;
262 ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state);
263 sampler_state.normalized_coords = 0;
264 ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state);
265
266 sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR;
267 sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
268 sampler_state.normalized_coords = 1;
269 ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state);
270 sampler_state.normalized_coords = 0;
271 ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state);
272
273 /* rasterizer state */
274 memset(&rs_state, 0, sizeof(rs_state));
275 rs_state.cull_face = PIPE_FACE_NONE;
276 rs_state.half_pixel_center = 1;
277 rs_state.bottom_edge_rule = 1;
278 rs_state.flatshade = 1;
279 rs_state.depth_clip = 1;
280 ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
281
282 rs_state.scissor = 1;
283 ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state);
284
285 if (ctx->has_stream_out) {
286 rs_state.scissor = 0;
287 rs_state.rasterizer_discard = 1;
288 ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state);
289 }
290
291 ctx->base.cb_slot = 0; /* 0 for now */
292 ctx->base.vb_slot = 0; /* 0 for now */
293
294 /* vertex elements states */
295 memset(&velem[0], 0, sizeof(velem[0]) * 2);
296 for (i = 0; i < 2; i++) {
297 velem[i].src_offset = i * 4 * sizeof(float);
298 velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
299 velem[i].vertex_buffer_index = ctx->base.vb_slot;
300 }
301 ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]);
302
303 if (ctx->has_stream_out) {
304 static enum pipe_format formats[4] = {
305 PIPE_FORMAT_R32_UINT,
306 PIPE_FORMAT_R32G32_UINT,
307 PIPE_FORMAT_R32G32B32_UINT,
308 PIPE_FORMAT_R32G32B32A32_UINT
309 };
310
311 for (i = 0; i < 4; i++) {
312 velem[0].src_format = formats[i];
313 velem[0].vertex_buffer_index = ctx->base.vb_slot;
314 ctx->velem_state_readbuf[i] =
315 pipe->create_vertex_elements_state(pipe, 1, &velem[0]);
316 }
317 }
318
319 ctx->has_layered =
320 pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) &&
321 pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
322
323 /* set invariant vertex coordinates */
324 for (i = 0; i < 4; i++)
325 ctx->vertices[i][0][3] = 1; /*v.w*/
326
327 return &ctx->base;
328 }
329
330 static void bind_vs_pos_only(struct blitter_context_priv *ctx,
331 unsigned num_so_channels)
332 {
333 struct pipe_context *pipe = ctx->base.pipe;
334 int index = num_so_channels ? num_so_channels - 1 : 0;
335
336 if (!ctx->vs_pos_only[index]) {
337 struct pipe_stream_output_info so;
338 static const enum tgsi_semantic semantic_names[] =
339 { TGSI_SEMANTIC_POSITION };
340 const uint semantic_indices[] = { 0 };
341
342 memset(&so, 0, sizeof(so));
343 so.num_outputs = 1;
344 so.output[0].num_components = num_so_channels;
345 so.stride[0] = num_so_channels;
346
347 ctx->vs_pos_only[index] =
348 util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names,
349 semantic_indices, false,
350 false, &so);
351 }
352
353 pipe->bind_vs_state(pipe, ctx->vs_pos_only[index]);
354 }
355
356 static void *get_vs_passthrough_pos_generic(struct blitter_context *blitter)
357 {
358 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
359 struct pipe_context *pipe = ctx->base.pipe;
360
361 if (!ctx->vs) {
362 static const enum tgsi_semantic semantic_names[] =
363 { TGSI_SEMANTIC_POSITION, TGSI_SEMANTIC_GENERIC };
364 const uint semantic_indices[] = { 0, 0 };
365 ctx->vs =
366 util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
367 semantic_indices, false);
368 }
369 return ctx->vs;
370 }
371
372 static void *get_vs_passthrough_pos(struct blitter_context *blitter)
373 {
374 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
375 struct pipe_context *pipe = ctx->base.pipe;
376
377 if (!ctx->vs_nogeneric) {
378 static const enum tgsi_semantic semantic_names[] =
379 { TGSI_SEMANTIC_POSITION };
380 const uint semantic_indices[] = { 0 };
381
382 ctx->vs_nogeneric =
383 util_make_vertex_passthrough_shader(pipe, 1,
384 semantic_names,
385 semantic_indices, false);
386 }
387 return ctx->vs_nogeneric;
388 }
389
390 static void *get_vs_layered(struct blitter_context *blitter)
391 {
392 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
393 struct pipe_context *pipe = ctx->base.pipe;
394
395 if (!ctx->vs_layered) {
396 ctx->vs_layered = util_make_layered_clear_vertex_shader(pipe);
397 }
398 return ctx->vs_layered;
399 }
400
401 static void bind_fs_empty(struct blitter_context_priv *ctx)
402 {
403 struct pipe_context *pipe = ctx->base.pipe;
404
405 if (!ctx->fs_empty) {
406 assert(!ctx->cached_all_shaders);
407 ctx->fs_empty = util_make_empty_fragment_shader(pipe);
408 }
409
410 ctx->bind_fs_state(pipe, ctx->fs_empty);
411 }
412
413 static void bind_fs_write_one_cbuf(struct blitter_context_priv *ctx)
414 {
415 struct pipe_context *pipe = ctx->base.pipe;
416
417 if (!ctx->fs_write_one_cbuf) {
418 assert(!ctx->cached_all_shaders);
419 ctx->fs_write_one_cbuf =
420 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
421 TGSI_INTERPOLATE_CONSTANT, false);
422 }
423
424 ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf);
425 }
426
427 static void bind_fs_write_all_cbufs(struct blitter_context_priv *ctx)
428 {
429 struct pipe_context *pipe = ctx->base.pipe;
430
431 if (!ctx->fs_write_all_cbufs) {
432 assert(!ctx->cached_all_shaders);
433 ctx->fs_write_all_cbufs =
434 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
435 TGSI_INTERPOLATE_CONSTANT, true);
436 }
437
438 ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs);
439 }
440
441 void util_blitter_destroy(struct blitter_context *blitter)
442 {
443 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
444 struct pipe_context *pipe = blitter->pipe;
445 unsigned i, j, f;
446
447 for (i = 0; i <= PIPE_MASK_RGBA; i++)
448 for (j = 0; j < 2; j++)
449 pipe->delete_blend_state(pipe, ctx->blend[i][j]);
450
451 for (i = 0; i < ARRAY_SIZE(ctx->blend_clear); i++) {
452 if (ctx->blend_clear[i])
453 pipe->delete_blend_state(pipe, ctx->blend_clear[i]);
454 }
455 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
456 pipe->delete_depth_stencil_alpha_state(pipe,
457 ctx->dsa_write_depth_keep_stencil);
458 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
459 pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
460
461 pipe->delete_rasterizer_state(pipe, ctx->rs_state);
462 pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor);
463 if (ctx->rs_discard_state)
464 pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state);
465 if (ctx->vs)
466 pipe->delete_vs_state(pipe, ctx->vs);
467 if (ctx->vs_nogeneric)
468 pipe->delete_vs_state(pipe, ctx->vs_nogeneric);
469 for (i = 0; i < 4; i++)
470 if (ctx->vs_pos_only[i])
471 pipe->delete_vs_state(pipe, ctx->vs_pos_only[i]);
472 if (ctx->vs_layered)
473 pipe->delete_vs_state(pipe, ctx->vs_layered);
474 pipe->delete_vertex_elements_state(pipe, ctx->velem_state);
475 for (i = 0; i < 4; i++) {
476 if (ctx->velem_state_readbuf[i]) {
477 pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]);
478 }
479 }
480
481 for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
482 for (unsigned type = 0; type < ARRAY_SIZE(ctx->fs_texfetch_col); ++type) {
483 for (unsigned inst = 0; inst < 2; inst++) {
484 if (ctx->fs_texfetch_col[type][i][inst])
485 ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[type][i][inst]);
486 }
487 if (ctx->fs_texfetch_col_msaa[type][i])
488 ctx->delete_fs_state(pipe, ctx->fs_texfetch_col_msaa[type][i]);
489 }
490
491 for (unsigned inst = 0; inst < 2; inst++) {
492 if (ctx->fs_texfetch_depth[i][inst])
493 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i][inst]);
494 if (ctx->fs_texfetch_depthstencil[i][inst])
495 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i][inst]);
496 if (ctx->fs_texfetch_stencil[i][inst])
497 ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i][inst]);
498 }
499
500 if (ctx->fs_texfetch_depth_msaa[i])
501 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth_msaa[i]);
502 if (ctx->fs_texfetch_depthstencil_msaa[i])
503 ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil_msaa[i]);
504 if (ctx->fs_texfetch_stencil_msaa[i])
505 ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil_msaa[i]);
506
507 for (j = 0; j< ARRAY_SIZE(ctx->fs_resolve[i]); j++)
508 for (f = 0; f < 2; f++)
509 if (ctx->fs_resolve[i][j][f])
510 ctx->delete_fs_state(pipe, ctx->fs_resolve[i][j][f]);
511 }
512
513 if (ctx->fs_empty)
514 ctx->delete_fs_state(pipe, ctx->fs_empty);
515 if (ctx->fs_write_one_cbuf)
516 ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf);
517 if (ctx->fs_write_all_cbufs)
518 ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs);
519
520 pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear);
521 pipe->delete_sampler_state(pipe, ctx->sampler_state_rect);
522 pipe->delete_sampler_state(pipe, ctx->sampler_state_linear);
523 pipe->delete_sampler_state(pipe, ctx->sampler_state);
524 FREE(ctx);
525 }
526
527 void util_blitter_set_texture_multisample(struct blitter_context *blitter,
528 bool supported)
529 {
530 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
531
532 ctx->has_texture_multisample = supported;
533 }
534
535 void util_blitter_set_running_flag(struct blitter_context *blitter)
536 {
537 if (blitter->running) {
538 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
539 __LINE__);
540 }
541 blitter->running = true;
542
543 blitter->pipe->set_active_query_state(blitter->pipe, false);
544 }
545
546 void util_blitter_unset_running_flag(struct blitter_context *blitter)
547 {
548 if (!blitter->running) {
549 _debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n",
550 __LINE__);
551 }
552 blitter->running = false;
553
554 blitter->pipe->set_active_query_state(blitter->pipe, true);
555 }
556
557 static void blitter_check_saved_vertex_states(MAYBE_UNUSED struct blitter_context_priv *ctx)
558 {
559 assert(ctx->base.saved_vs != INVALID_PTR);
560 assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR);
561 assert(!ctx->has_tessellation || ctx->base.saved_tcs != INVALID_PTR);
562 assert(!ctx->has_tessellation || ctx->base.saved_tes != INVALID_PTR);
563 assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0u);
564 assert(ctx->base.saved_rs_state != INVALID_PTR);
565 }
566
567 void util_blitter_restore_vertex_states(struct blitter_context *blitter)
568 {
569 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
570 struct pipe_context *pipe = ctx->base.pipe;
571 unsigned i;
572
573 /* Vertex buffer. */
574 if (ctx->base.saved_vertex_buffer.buffer.resource) {
575 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1,
576 &ctx->base.saved_vertex_buffer);
577 pipe_vertex_buffer_unreference(&ctx->base.saved_vertex_buffer);
578 }
579
580 /* Vertex elements. */
581 if (ctx->base.saved_velem_state != INVALID_PTR) {
582 pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state);
583 ctx->base.saved_velem_state = INVALID_PTR;
584 }
585
586 /* Vertex shader. */
587 pipe->bind_vs_state(pipe, ctx->base.saved_vs);
588 ctx->base.saved_vs = INVALID_PTR;
589
590 /* Geometry shader. */
591 if (ctx->has_geometry_shader) {
592 pipe->bind_gs_state(pipe, ctx->base.saved_gs);
593 ctx->base.saved_gs = INVALID_PTR;
594 }
595
596 if (ctx->has_tessellation) {
597 pipe->bind_tcs_state(pipe, ctx->base.saved_tcs);
598 pipe->bind_tes_state(pipe, ctx->base.saved_tes);
599 ctx->base.saved_tcs = INVALID_PTR;
600 ctx->base.saved_tes = INVALID_PTR;
601 }
602
603 /* Stream outputs. */
604 if (ctx->has_stream_out) {
605 unsigned offsets[PIPE_MAX_SO_BUFFERS];
606 for (i = 0; i < ctx->base.saved_num_so_targets; i++)
607 offsets[i] = (unsigned)-1;
608 pipe->set_stream_output_targets(pipe,
609 ctx->base.saved_num_so_targets,
610 ctx->base.saved_so_targets, offsets);
611
612 for (i = 0; i < ctx->base.saved_num_so_targets; i++)
613 pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL);
614
615 ctx->base.saved_num_so_targets = ~0;
616 }
617
618 /* Rasterizer. */
619 pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state);
620 ctx->base.saved_rs_state = INVALID_PTR;
621 }
622
623 static void blitter_check_saved_fragment_states(MAYBE_UNUSED struct blitter_context_priv *ctx)
624 {
625 assert(ctx->base.saved_fs != INVALID_PTR);
626 assert(ctx->base.saved_dsa_state != INVALID_PTR);
627 assert(ctx->base.saved_blend_state != INVALID_PTR);
628 }
629
630 void util_blitter_restore_fragment_states(struct blitter_context *blitter)
631 {
632 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
633 struct pipe_context *pipe = ctx->base.pipe;
634
635 /* Fragment shader. */
636 ctx->bind_fs_state(pipe, ctx->base.saved_fs);
637 ctx->base.saved_fs = INVALID_PTR;
638
639 /* Depth, stencil, alpha. */
640 pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state);
641 ctx->base.saved_dsa_state = INVALID_PTR;
642
643 /* Blend state. */
644 pipe->bind_blend_state(pipe, ctx->base.saved_blend_state);
645 ctx->base.saved_blend_state = INVALID_PTR;
646
647 /* Sample mask. */
648 if (ctx->base.is_sample_mask_saved) {
649 pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask);
650 ctx->base.is_sample_mask_saved = false;
651 }
652
653 /* Miscellaneous states. */
654 /* XXX check whether these are saved and whether they need to be restored
655 * (depending on the operation) */
656 pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
657
658 if (!blitter->skip_viewport_restore)
659 pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport);
660 }
661
662 static void blitter_check_saved_fb_state(MAYBE_UNUSED struct blitter_context_priv *ctx)
663 {
664 assert(ctx->base.saved_fb_state.nr_cbufs != (ubyte) ~0);
665 }
666
667 static void blitter_disable_render_cond(struct blitter_context_priv *ctx)
668 {
669 struct pipe_context *pipe = ctx->base.pipe;
670
671 if (ctx->base.saved_render_cond_query) {
672 pipe->render_condition(pipe, NULL, false, 0);
673 }
674 }
675
676 void util_blitter_restore_render_cond(struct blitter_context *blitter)
677 {
678 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
679 struct pipe_context *pipe = ctx->base.pipe;
680
681 if (ctx->base.saved_render_cond_query) {
682 pipe->render_condition(pipe, ctx->base.saved_render_cond_query,
683 ctx->base.saved_render_cond_cond,
684 ctx->base.saved_render_cond_mode);
685 ctx->base.saved_render_cond_query = NULL;
686 }
687 }
688
689 void util_blitter_restore_fb_state(struct blitter_context *blitter)
690 {
691 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
692 struct pipe_context *pipe = ctx->base.pipe;
693
694 pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state);
695 util_unreference_framebuffer_state(&ctx->base.saved_fb_state);
696 }
697
698 static void blitter_check_saved_textures(MAYBE_UNUSED struct blitter_context_priv *ctx)
699 {
700 assert(ctx->base.saved_num_sampler_states != ~0u);
701 assert(ctx->base.saved_num_sampler_views != ~0u);
702 }
703
704 void util_blitter_restore_textures(struct blitter_context *blitter)
705 {
706 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
707 struct pipe_context *pipe = ctx->base.pipe;
708 unsigned i;
709
710 /* Fragment sampler states. */
711 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
712 ctx->base.saved_num_sampler_states,
713 ctx->base.saved_sampler_states);
714
715 ctx->base.saved_num_sampler_states = ~0;
716
717 /* Fragment sampler views. */
718 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
719 ctx->base.saved_num_sampler_views,
720 ctx->base.saved_sampler_views);
721
722 for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
723 pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL);
724
725 ctx->base.saved_num_sampler_views = ~0;
726 }
727
728 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter)
729 {
730 struct pipe_context *pipe = blitter->pipe;
731
732 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
733 &blitter->saved_fs_constant_buffer);
734 pipe_resource_reference(&blitter->saved_fs_constant_buffer.buffer, NULL);
735 }
736
737 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
738 int x1, int y1, int x2, int y2,
739 float depth)
740 {
741 int i;
742
743 /* set vertex positions */
744 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
745 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
746
747 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
748 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
749
750 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
751 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
752
753 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
754 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
755
756 for (i = 0; i < 4; i++)
757 ctx->vertices[i][0][2] = depth; /*z*/
758
759 /* viewport */
760 struct pipe_viewport_state viewport;
761 viewport.scale[0] = 0.5f * ctx->dst_width;
762 viewport.scale[1] = 0.5f * ctx->dst_height;
763 viewport.scale[2] = 1.0f;
764 viewport.translate[0] = 0.5f * ctx->dst_width;
765 viewport.translate[1] = 0.5f * ctx->dst_height;
766 viewport.translate[2] = 0.0f;
767 ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport);
768 }
769
770 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
771 const float color[4])
772 {
773 int i;
774
775 if (color) {
776 for (i = 0; i < 4; i++)
777 memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
778 } else {
779 for (i = 0; i < 4; i++)
780 memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
781 }
782 }
783
784 static void get_texcoords(struct pipe_sampler_view *src,
785 unsigned src_width0, unsigned src_height0,
786 int x1, int y1, int x2, int y2,
787 float layer, unsigned sample,
788 bool uses_txf, union blitter_attrib *out)
789 {
790 unsigned level = src->u.tex.first_level;
791 bool normalized = !uses_txf &&
792 src->target != PIPE_TEXTURE_RECT &&
793 src->texture->nr_samples <= 1;
794
795 if (normalized) {
796 out->texcoord.x1 = x1 / (float)u_minify(src_width0, level);
797 out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
798 out->texcoord.x2 = x2 / (float)u_minify(src_width0, level);
799 out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
800 } else {
801 out->texcoord.x1 = x1;
802 out->texcoord.y1 = y1;
803 out->texcoord.x2 = x2;
804 out->texcoord.y2 = y2;
805 }
806
807 out->texcoord.z = 0;
808 out->texcoord.w = 0;
809
810 /* Set the layer. */
811 switch (src->target) {
812 case PIPE_TEXTURE_3D:
813 {
814 float r = layer;
815
816 if (!uses_txf)
817 r /= u_minify(src->texture->depth0, src->u.tex.first_level);
818
819 out->texcoord.z = r;
820 }
821 break;
822
823 case PIPE_TEXTURE_1D_ARRAY:
824 out->texcoord.y1 = out->texcoord.y2 = layer;
825 break;
826
827 case PIPE_TEXTURE_2D_ARRAY:
828 out->texcoord.z = layer;
829 out->texcoord.w = sample;
830 break;
831
832 case PIPE_TEXTURE_CUBE_ARRAY:
833 out->texcoord.w = (unsigned)layer / 6;
834 break;
835
836 case PIPE_TEXTURE_2D:
837 out->texcoord.w = sample;
838 break;
839
840 default:;
841 }
842 }
843
844 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
845 unsigned width, unsigned height)
846 {
847 ctx->dst_width = width;
848 ctx->dst_height = height;
849 }
850
851 static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
852 float *out, unsigned stride)
853 {
854 out[0] = attrib->texcoord.x1;
855 out[1] = attrib->texcoord.y1;
856 out += stride;
857 out[0] = attrib->texcoord.x2;
858 out[1] = attrib->texcoord.y1;
859 out += stride;
860 out[0] = attrib->texcoord.x2;
861 out[1] = attrib->texcoord.y2;
862 out += stride;
863 out[0] = attrib->texcoord.x1;
864 out[1] = attrib->texcoord.y2;
865 }
866
867 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
868 enum pipe_format src_format,
869 enum pipe_format dst_format,
870 enum pipe_texture_target target,
871 unsigned src_nr_samples,
872 unsigned dst_nr_samples,
873 unsigned filter,
874 bool use_txf)
875 {
876 struct pipe_context *pipe = ctx->base.pipe;
877 enum tgsi_texture_type tgsi_tex =
878 util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
879 enum tgsi_return_type stype;
880 enum tgsi_return_type dtype;
881 unsigned type;
882
883 assert(target < PIPE_MAX_TEXTURE_TYPES);
884
885 if (util_format_is_pure_uint(src_format)) {
886 stype = TGSI_RETURN_TYPE_UINT;
887 if (util_format_is_pure_uint(dst_format)) {
888 dtype = TGSI_RETURN_TYPE_UINT;
889 type = 0;
890 } else {
891 assert(util_format_is_pure_sint(dst_format));
892 dtype = TGSI_RETURN_TYPE_SINT;
893 type = 1;
894 }
895 } else if (util_format_is_pure_sint(src_format)) {
896 stype = TGSI_RETURN_TYPE_SINT;
897 if (util_format_is_pure_sint(dst_format)) {
898 dtype = TGSI_RETURN_TYPE_SINT;
899 type = 2;
900 } else {
901 assert(util_format_is_pure_uint(dst_format));
902 dtype = TGSI_RETURN_TYPE_UINT;
903 type = 3;
904 }
905 } else {
906 assert(!util_format_is_pure_uint(dst_format) &&
907 !util_format_is_pure_sint(dst_format));
908 dtype = stype = TGSI_RETURN_TYPE_FLOAT;
909 type = 4;
910 }
911
912 if (src_nr_samples > 1) {
913 void **shader;
914
915 /* OpenGL requires that integer textures just copy 1 sample instead
916 * of averaging.
917 */
918 if (dst_nr_samples <= 1 &&
919 stype != TGSI_RETURN_TYPE_UINT &&
920 stype != TGSI_RETURN_TYPE_SINT) {
921 /* The destination has one sample, so we'll do color resolve. */
922 unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
923
924 assert(filter < 2);
925
926 shader = &ctx->fs_resolve[target][index][filter];
927
928 if (!*shader) {
929 assert(!ctx->cached_all_shaders);
930 if (filter == PIPE_TEX_FILTER_LINEAR) {
931 *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
932 src_nr_samples,
933 stype);
934 }
935 else {
936 *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
937 src_nr_samples,
938 stype);
939 }
940 }
941 }
942 else {
943 /* The destination has multiple samples, we'll do
944 * an MSAA->MSAA copy.
945 */
946 shader = &ctx->fs_texfetch_col_msaa[type][target];
947
948 /* Create the fragment shader on-demand. */
949 if (!*shader) {
950 assert(!ctx->cached_all_shaders);
951 *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype);
952 }
953 }
954
955 return *shader;
956 } else {
957 void **shader;
958
959 if (use_txf)
960 shader = &ctx->fs_texfetch_col[type][target][1];
961 else
962 shader = &ctx->fs_texfetch_col[type][target][0];
963
964 /* Create the fragment shader on-demand. */
965 if (!*shader) {
966 assert(!ctx->cached_all_shaders);
967 *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
968 TGSI_INTERPOLATE_LINEAR,
969 stype, dtype,
970 ctx->has_tex_lz, use_txf);
971 }
972
973 return *shader;
974 }
975 }
976
977 static inline
978 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
979 enum pipe_texture_target target,
980 unsigned nr_samples,
981 bool use_txf)
982 {
983 struct pipe_context *pipe = ctx->base.pipe;
984
985 assert(target < PIPE_MAX_TEXTURE_TYPES);
986
987 if (nr_samples > 1) {
988 void **shader = &ctx->fs_texfetch_depth_msaa[target];
989
990 /* Create the fragment shader on-demand. */
991 if (!*shader) {
992 enum tgsi_texture_type tgsi_tex;
993 assert(!ctx->cached_all_shaders);
994 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
995 *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
996 }
997
998 return *shader;
999 } else {
1000 void **shader;
1001
1002 if (use_txf)
1003 shader = &ctx->fs_texfetch_depth[target][1];
1004 else
1005 shader = &ctx->fs_texfetch_depth[target][0];
1006
1007 /* Create the fragment shader on-demand. */
1008 if (!*shader) {
1009 enum tgsi_texture_type tgsi_tex;
1010 assert(!ctx->cached_all_shaders);
1011 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1012 *shader =
1013 util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
1014 TGSI_INTERPOLATE_LINEAR,
1015 ctx->has_tex_lz, use_txf);
1016 }
1017
1018 return *shader;
1019 }
1020 }
1021
1022 static inline
1023 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
1024 enum pipe_texture_target target,
1025 unsigned nr_samples,
1026 bool use_txf)
1027 {
1028 struct pipe_context *pipe = ctx->base.pipe;
1029
1030 assert(target < PIPE_MAX_TEXTURE_TYPES);
1031
1032 if (nr_samples > 1) {
1033 void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
1034
1035 /* Create the fragment shader on-demand. */
1036 if (!*shader) {
1037 enum tgsi_texture_type tgsi_tex;
1038 assert(!ctx->cached_all_shaders);
1039 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1040 *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
1041 }
1042
1043 return *shader;
1044 } else {
1045 void **shader;
1046
1047 if (use_txf)
1048 shader = &ctx->fs_texfetch_depthstencil[target][1];
1049 else
1050 shader = &ctx->fs_texfetch_depthstencil[target][0];
1051
1052 /* Create the fragment shader on-demand. */
1053 if (!*shader) {
1054 enum tgsi_texture_type tgsi_tex;
1055 assert(!ctx->cached_all_shaders);
1056 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1057 *shader =
1058 util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex,
1059 TGSI_INTERPOLATE_LINEAR,
1060 ctx->has_tex_lz,
1061 use_txf);
1062 }
1063
1064 return *shader;
1065 }
1066 }
1067
1068 static inline
1069 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
1070 enum pipe_texture_target target,
1071 unsigned nr_samples,
1072 bool use_txf)
1073 {
1074 struct pipe_context *pipe = ctx->base.pipe;
1075
1076 assert(target < PIPE_MAX_TEXTURE_TYPES);
1077
1078 if (nr_samples > 1) {
1079 void **shader = &ctx->fs_texfetch_stencil_msaa[target];
1080
1081 /* Create the fragment shader on-demand. */
1082 if (!*shader) {
1083 enum tgsi_texture_type tgsi_tex;
1084 assert(!ctx->cached_all_shaders);
1085 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1086 *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
1087 }
1088
1089 return *shader;
1090 } else {
1091 void **shader;
1092
1093 if (use_txf)
1094 shader = &ctx->fs_texfetch_stencil[target][1];
1095 else
1096 shader = &ctx->fs_texfetch_stencil[target][0];
1097
1098 /* Create the fragment shader on-demand. */
1099 if (!*shader) {
1100 enum tgsi_texture_type tgsi_tex;
1101 assert(!ctx->cached_all_shaders);
1102 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1103 *shader =
1104 util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex,
1105 TGSI_INTERPOLATE_LINEAR,
1106 ctx->has_tex_lz, use_txf);
1107 }
1108
1109 return *shader;
1110 }
1111 }
1112
1113
1114 /**
1115 * Generate and save all fragment shaders that we will ever need for
1116 * blitting. Drivers which use the 'draw' fallbacks will typically use
1117 * this to make sure we generate/use shaders that don't go through the
1118 * draw module's wrapper functions.
1119 */
1120 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
1121 {
1122 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1123 struct pipe_context *pipe = blitter->pipe;
1124 struct pipe_screen *screen = pipe->screen;
1125 unsigned samples, j, f, target, max_samples, use_txf;
1126 bool has_arraytex, has_cubearraytex;
1127
1128 max_samples = ctx->has_texture_multisample ? 2 : 1;
1129 has_arraytex = screen->get_param(screen,
1130 PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
1131 has_cubearraytex = screen->get_param(screen,
1132 PIPE_CAP_CUBE_MAP_ARRAY) != 0;
1133
1134 /* It only matters if i <= 1 or > 1. */
1135 for (samples = 1; samples <= max_samples; samples++) {
1136 for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
1137 for (use_txf = 0; use_txf <= ctx->has_txf; use_txf++) {
1138 if (!has_arraytex &&
1139 (target == PIPE_TEXTURE_1D_ARRAY ||
1140 target == PIPE_TEXTURE_2D_ARRAY)) {
1141 continue;
1142 }
1143 if (!has_cubearraytex &&
1144 (target == PIPE_TEXTURE_CUBE_ARRAY))
1145 continue;
1146
1147 if (samples > 1 &&
1148 (target != PIPE_TEXTURE_2D &&
1149 target != PIPE_TEXTURE_2D_ARRAY))
1150 continue;
1151
1152 if (samples > 1 && use_txf)
1153 continue; /* TXF is the only option, use_txf has no effect */
1154
1155 /* If samples == 1, the shaders read one texel. If samples >= 1,
1156 * they read one sample.
1157 */
1158 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1159 PIPE_FORMAT_R32_FLOAT, target,
1160 samples, samples, 0, use_txf);
1161 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1162 PIPE_FORMAT_R32_UINT, target,
1163 samples, samples, 0, use_txf);
1164 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1165 PIPE_FORMAT_R32_SINT, target,
1166 samples, samples, 0, use_txf);
1167 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1168 PIPE_FORMAT_R32_SINT, target,
1169 samples, samples, 0, use_txf);
1170 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1171 PIPE_FORMAT_R32_UINT, target,
1172 samples, samples, 0, use_txf);
1173 blitter_get_fs_texfetch_depth(ctx, target, samples, use_txf);
1174 if (ctx->has_stencil_export) {
1175 blitter_get_fs_texfetch_depthstencil(ctx, target, samples, use_txf);
1176 blitter_get_fs_texfetch_stencil(ctx, target, samples, use_txf);
1177 }
1178
1179 if (samples == 1)
1180 continue;
1181
1182 /* MSAA resolve shaders. */
1183 for (j = 2; j < 32; j++) {
1184 if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT,
1185 target, j,
1186 PIPE_BIND_SAMPLER_VIEW)) {
1187 continue;
1188 }
1189
1190 for (f = 0; f < 2; f++) {
1191 if (f != PIPE_TEX_FILTER_NEAREST && use_txf)
1192 continue;
1193
1194 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1195 PIPE_FORMAT_R32_FLOAT, target,
1196 j, 1, f, use_txf);
1197 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1198 PIPE_FORMAT_R32_UINT, target,
1199 j, 1, f, use_txf);
1200 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1201 PIPE_FORMAT_R32_SINT, target,
1202 j, 1, f, use_txf);
1203 }
1204 }
1205 }
1206 }
1207 }
1208
1209 ctx->fs_empty = util_make_empty_fragment_shader(pipe);
1210
1211 ctx->fs_write_one_cbuf =
1212 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1213 TGSI_INTERPOLATE_CONSTANT, false);
1214
1215 ctx->fs_write_all_cbufs =
1216 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1217 TGSI_INTERPOLATE_CONSTANT, true);
1218
1219 ctx->cached_all_shaders = true;
1220 }
1221
1222 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
1223 bool scissor)
1224 {
1225 struct pipe_context *pipe = ctx->base.pipe;
1226
1227 pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor
1228 : ctx->rs_state);
1229 if (ctx->has_geometry_shader)
1230 pipe->bind_gs_state(pipe, NULL);
1231 if (ctx->has_tessellation) {
1232 pipe->bind_tcs_state(pipe, NULL);
1233 pipe->bind_tes_state(pipe, NULL);
1234 }
1235 if (ctx->has_stream_out)
1236 pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
1237 }
1238
1239 static void blitter_draw(struct blitter_context_priv *ctx,
1240 void *vertex_elements_cso,
1241 blitter_get_vs_func get_vs,
1242 int x1, int y1, int x2, int y2, float depth,
1243 unsigned num_instances)
1244 {
1245 struct pipe_context *pipe = ctx->base.pipe;
1246 struct pipe_vertex_buffer vb = {0};
1247
1248 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
1249
1250 vb.stride = 8 * sizeof(float);
1251
1252 u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices,
1253 &vb.buffer_offset, &vb.buffer.resource);
1254 if (!vb.buffer.resource)
1255 return;
1256 u_upload_unmap(pipe->stream_uploader);
1257
1258 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
1259 pipe->bind_vertex_elements_state(pipe, vertex_elements_cso);
1260 pipe->bind_vs_state(pipe, get_vs(&ctx->base));
1261
1262 if (ctx->base.use_index_buffer) {
1263 /* Note that for V3D,
1264 * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require
1265 * that the last vert of the two tris be the same.
1266 */
1267 static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 };
1268 util_draw_elements_instanced(pipe, indices, 1, 0,
1269 PIPE_PRIM_TRIANGLES, 0, 6,
1270 0, num_instances);
1271 } else {
1272 util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
1273 0, num_instances);
1274 }
1275 pipe_resource_reference(&vb.buffer.resource, NULL);
1276 }
1277
1278 void util_blitter_draw_rectangle(struct blitter_context *blitter,
1279 void *vertex_elements_cso,
1280 blitter_get_vs_func get_vs,
1281 int x1, int y1, int x2, int y2,
1282 float depth, unsigned num_instances,
1283 enum blitter_attrib_type type,
1284 const union blitter_attrib *attrib)
1285 {
1286 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1287 unsigned i;
1288
1289 switch (type) {
1290 case UTIL_BLITTER_ATTRIB_COLOR:
1291 blitter_set_clear_color(ctx, attrib->color);
1292 break;
1293
1294 case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
1295 for (i = 0; i < 4; i++) {
1296 ctx->vertices[i][1][2] = attrib->texcoord.z;
1297 ctx->vertices[i][1][3] = attrib->texcoord.w;
1298 }
1299 /* fall through */
1300 case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
1301 set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
1302 break;
1303
1304 default:;
1305 }
1306
1307 blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth,
1308 num_instances);
1309 }
1310
1311 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
1312 unsigned clear_buffers)
1313 {
1314 struct pipe_context *pipe = ctx->base.pipe;
1315 int index;
1316
1317 clear_buffers &= PIPE_CLEAR_COLOR;
1318
1319 /* Return an existing blend state. */
1320 if (!clear_buffers)
1321 return ctx->blend[0][0];
1322
1323 index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers);
1324
1325 if (ctx->blend_clear[index])
1326 return ctx->blend_clear[index];
1327
1328 /* Create a new one. */
1329 {
1330 struct pipe_blend_state blend = {0};
1331 unsigned i;
1332
1333 blend.independent_blend_enable = 1;
1334
1335 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1336 if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
1337 blend.rt[i].colormask = PIPE_MASK_RGBA;
1338 }
1339 }
1340
1341 ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend);
1342 }
1343 return ctx->blend_clear[index];
1344 }
1345
1346 void util_blitter_common_clear_setup(struct blitter_context *blitter,
1347 unsigned width, unsigned height,
1348 unsigned clear_buffers,
1349 void *custom_blend, void *custom_dsa)
1350 {
1351 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1352 struct pipe_context *pipe = ctx->base.pipe;
1353
1354 util_blitter_set_running_flag(blitter);
1355 blitter_check_saved_vertex_states(ctx);
1356 blitter_check_saved_fragment_states(ctx);
1357 blitter_disable_render_cond(ctx);
1358
1359 /* bind states */
1360 if (custom_blend) {
1361 pipe->bind_blend_state(pipe, custom_blend);
1362 } else {
1363 pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers));
1364 }
1365
1366 if (custom_dsa) {
1367 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1368 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1369 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1370 } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1371 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1372 } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1373 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1374 } else {
1375 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1376 }
1377
1378 pipe->set_sample_mask(pipe, ~0);
1379 blitter_set_dst_dimensions(ctx, width, height);
1380 }
1381
1382 static void util_blitter_clear_custom(struct blitter_context *blitter,
1383 unsigned width, unsigned height,
1384 unsigned num_layers,
1385 unsigned clear_buffers,
1386 const union pipe_color_union *color,
1387 double depth, unsigned stencil,
1388 void *custom_blend, void *custom_dsa)
1389 {
1390 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1391 struct pipe_context *pipe = ctx->base.pipe;
1392 struct pipe_stencil_ref sr = { { 0 } };
1393
1394 assert(ctx->has_layered || num_layers <= 1);
1395
1396 util_blitter_common_clear_setup(blitter, width, height, clear_buffers,
1397 custom_blend, custom_dsa);
1398
1399 sr.ref_value[0] = stencil & 0xff;
1400 pipe->set_stencil_ref(pipe, &sr);
1401
1402 bind_fs_write_all_cbufs(ctx);
1403
1404 union blitter_attrib attrib;
1405 memcpy(attrib.color, color->ui, sizeof(color->ui));
1406
1407 bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0;
1408 enum blitter_attrib_type type = pass_generic ? UTIL_BLITTER_ATTRIB_COLOR :
1409 UTIL_BLITTER_ATTRIB_NONE;
1410
1411 if (num_layers > 1 && ctx->has_layered) {
1412 blitter_get_vs_func get_vs = get_vs_layered;
1413
1414 blitter_set_common_draw_rect_state(ctx, false);
1415 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1416 0, 0, width, height,
1417 (float) depth, num_layers, type, &attrib);
1418 } else {
1419 blitter_get_vs_func get_vs;
1420
1421 if (pass_generic)
1422 get_vs = get_vs_passthrough_pos_generic;
1423 else
1424 get_vs = get_vs_passthrough_pos;
1425
1426 blitter_set_common_draw_rect_state(ctx, false);
1427 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1428 0, 0, width, height,
1429 (float) depth, 1, type, &attrib);
1430 }
1431
1432 util_blitter_restore_vertex_states(blitter);
1433 util_blitter_restore_fragment_states(blitter);
1434 util_blitter_restore_render_cond(blitter);
1435 util_blitter_unset_running_flag(blitter);
1436 }
1437
1438 void util_blitter_clear(struct blitter_context *blitter,
1439 unsigned width, unsigned height, unsigned num_layers,
1440 unsigned clear_buffers,
1441 const union pipe_color_union *color,
1442 double depth, unsigned stencil)
1443 {
1444 util_blitter_clear_custom(blitter, width, height, num_layers,
1445 clear_buffers, color, depth, stencil,
1446 NULL, NULL);
1447 }
1448
1449 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1450 unsigned width, unsigned height,
1451 double depth, void *custom_dsa)
1452 {
1453 static const union pipe_color_union color;
1454 util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0,
1455 NULL, custom_dsa);
1456 }
1457
1458 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1459 struct pipe_resource *dst,
1460 unsigned dstlevel,
1461 unsigned dstz)
1462 {
1463 memset(dst_templ, 0, sizeof(*dst_templ));
1464 dst_templ->format = util_format_linear(dst->format);
1465 dst_templ->u.tex.level = dstlevel;
1466 dst_templ->u.tex.first_layer = dstz;
1467 dst_templ->u.tex.last_layer = dstz;
1468 }
1469
1470 static struct pipe_surface *
1471 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1472 struct pipe_surface *surf)
1473 {
1474 struct pipe_surface dst_templ;
1475
1476 memset(&dst_templ, 0, sizeof(dst_templ));
1477 dst_templ.format = surf->format;
1478 dst_templ.u.tex.level = surf->u.tex.level;
1479 dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1480 dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1481
1482 return pipe->create_surface(pipe, surf->texture, &dst_templ);
1483 }
1484
1485 void util_blitter_default_src_texture(struct blitter_context *blitter,
1486 struct pipe_sampler_view *src_templ,
1487 struct pipe_resource *src,
1488 unsigned srclevel)
1489 {
1490 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1491
1492 memset(src_templ, 0, sizeof(*src_templ));
1493
1494 if (ctx->cube_as_2darray &&
1495 (src->target == PIPE_TEXTURE_CUBE ||
1496 src->target == PIPE_TEXTURE_CUBE_ARRAY))
1497 src_templ->target = PIPE_TEXTURE_2D_ARRAY;
1498 else
1499 src_templ->target = src->target;
1500
1501 src_templ->format = util_format_linear(src->format);
1502 src_templ->u.tex.first_level = srclevel;
1503 src_templ->u.tex.last_level = srclevel;
1504 src_templ->u.tex.first_layer = 0;
1505 src_templ->u.tex.last_layer =
1506 src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1507 : (unsigned)(src->array_size - 1);
1508 src_templ->swizzle_r = PIPE_SWIZZLE_X;
1509 src_templ->swizzle_g = PIPE_SWIZZLE_Y;
1510 src_templ->swizzle_b = PIPE_SWIZZLE_Z;
1511 src_templ->swizzle_a = PIPE_SWIZZLE_W;
1512 }
1513
1514 static bool is_blit_generic_supported(struct blitter_context *blitter,
1515 const struct pipe_resource *dst,
1516 enum pipe_format dst_format,
1517 const struct pipe_resource *src,
1518 enum pipe_format src_format,
1519 unsigned mask)
1520 {
1521 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1522 struct pipe_screen *screen = ctx->base.pipe->screen;
1523
1524 if (dst) {
1525 unsigned bind;
1526 const struct util_format_description *desc =
1527 util_format_description(dst_format);
1528 bool dst_has_stencil = util_format_has_stencil(desc);
1529
1530 /* Stencil export must be supported for stencil copy. */
1531 if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1532 !ctx->has_stencil_export) {
1533 return false;
1534 }
1535
1536 if (dst_has_stencil || util_format_has_depth(desc))
1537 bind = PIPE_BIND_DEPTH_STENCIL;
1538 else
1539 bind = PIPE_BIND_RENDER_TARGET;
1540
1541 if (!screen->is_format_supported(screen, dst_format, dst->target,
1542 dst->nr_samples, bind)) {
1543 return false;
1544 }
1545 }
1546
1547 if (src) {
1548 if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1549 return false;
1550 }
1551
1552 if (!screen->is_format_supported(screen, src_format, src->target,
1553 src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) {
1554 return false;
1555 }
1556
1557 /* Check stencil sampler support for stencil copy. */
1558 if (mask & PIPE_MASK_S) {
1559 if (util_format_has_stencil(util_format_description(src_format))) {
1560 enum pipe_format stencil_format =
1561 util_format_stencil_only(src_format);
1562 assert(stencil_format != PIPE_FORMAT_NONE);
1563
1564 if (stencil_format != src_format &&
1565 !screen->is_format_supported(screen, stencil_format,
1566 src->target, src->nr_samples,
1567 PIPE_BIND_SAMPLER_VIEW)) {
1568 return false;
1569 }
1570 }
1571 }
1572 }
1573
1574 return true;
1575 }
1576
1577 bool util_blitter_is_copy_supported(struct blitter_context *blitter,
1578 const struct pipe_resource *dst,
1579 const struct pipe_resource *src)
1580 {
1581 return is_blit_generic_supported(blitter, dst, dst->format,
1582 src, src->format, PIPE_MASK_RGBAZS);
1583 }
1584
1585 bool util_blitter_is_blit_supported(struct blitter_context *blitter,
1586 const struct pipe_blit_info *info)
1587 {
1588 return is_blit_generic_supported(blitter,
1589 info->dst.resource, info->dst.format,
1590 info->src.resource, info->src.format,
1591 info->mask);
1592 }
1593
1594 void util_blitter_copy_texture(struct blitter_context *blitter,
1595 struct pipe_resource *dst,
1596 unsigned dst_level,
1597 unsigned dstx, unsigned dsty, unsigned dstz,
1598 struct pipe_resource *src,
1599 unsigned src_level,
1600 const struct pipe_box *srcbox)
1601 {
1602 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1603 struct pipe_context *pipe = ctx->base.pipe;
1604 struct pipe_surface *dst_view, dst_templ;
1605 struct pipe_sampler_view src_templ, *src_view;
1606 struct pipe_box dstbox;
1607
1608 assert(dst && src);
1609 assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1610
1611 u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1612 abs(srcbox->depth), &dstbox);
1613
1614 /* Initialize the surface. */
1615 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1616 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1617
1618 /* Initialize the sampler view. */
1619 util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
1620 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1621
1622 /* Copy. */
1623 util_blitter_blit_generic(blitter, dst_view, &dstbox,
1624 src_view, srcbox, src->width0, src->height0,
1625 PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
1626 false);
1627
1628 pipe_surface_reference(&dst_view, NULL);
1629 pipe_sampler_view_reference(&src_view, NULL);
1630 }
1631
1632 static void
1633 blitter_draw_tex(struct blitter_context_priv *ctx,
1634 int dst_x1, int dst_y1, int dst_x2, int dst_y2,
1635 struct pipe_sampler_view *src,
1636 unsigned src_width0, unsigned src_height0,
1637 int src_x1, int src_y1, int src_x2, int src_y2,
1638 float layer, unsigned sample,
1639 bool uses_txf, enum blitter_attrib_type type)
1640 {
1641 union blitter_attrib coord;
1642 blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic;
1643
1644 get_texcoords(src, src_width0, src_height0,
1645 src_x1, src_y1, src_x2, src_y2, layer, sample,
1646 uses_txf, &coord);
1647
1648 if (src->target == PIPE_TEXTURE_CUBE ||
1649 src->target == PIPE_TEXTURE_CUBE_ARRAY) {
1650 float face_coord[4][2];
1651
1652 set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
1653 util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
1654 /* pointer, stride in floats */
1655 &face_coord[0][0], 2,
1656 &ctx->vertices[0][1][0], 8,
1657 false);
1658 for (unsigned i = 0; i < 4; i++)
1659 ctx->vertices[i][1][3] = coord.texcoord.w;
1660
1661 /* Cubemaps don't use draw_rectangle. */
1662 blitter_draw(ctx, ctx->velem_state, get_vs,
1663 dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
1664 } else {
1665 ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs,
1666 dst_x1, dst_y1, dst_x2, dst_y2,
1667 0, 1, type, &coord);
1668 }
1669 }
1670
1671 static void do_blits(struct blitter_context_priv *ctx,
1672 struct pipe_surface *dst,
1673 const struct pipe_box *dstbox,
1674 struct pipe_sampler_view *src,
1675 unsigned src_width0,
1676 unsigned src_height0,
1677 const struct pipe_box *srcbox,
1678 bool is_zsbuf,
1679 bool uses_txf)
1680 {
1681 struct pipe_context *pipe = ctx->base.pipe;
1682 unsigned src_samples = src->texture->nr_samples;
1683 unsigned dst_samples = dst->texture->nr_samples;
1684 enum pipe_texture_target src_target = src->target;
1685 struct pipe_framebuffer_state fb_state = {0};
1686
1687 /* Initialize framebuffer state. */
1688 fb_state.width = dst->width;
1689 fb_state.height = dst->height;
1690 fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1691
1692 blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1693
1694 if ((src_target == PIPE_TEXTURE_1D ||
1695 src_target == PIPE_TEXTURE_2D ||
1696 src_target == PIPE_TEXTURE_RECT) &&
1697 src_samples <= 1) {
1698 /* Set framebuffer state. */
1699 if (is_zsbuf) {
1700 fb_state.zsbuf = dst;
1701 } else {
1702 fb_state.cbufs[0] = dst;
1703 }
1704 pipe->set_framebuffer_state(pipe, &fb_state);
1705
1706 /* Draw. */
1707 pipe->set_sample_mask(pipe, ~0);
1708 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1709 dstbox->x + dstbox->width,
1710 dstbox->y + dstbox->height,
1711 src, src_width0, src_height0, srcbox->x, srcbox->y,
1712 srcbox->x + srcbox->width, srcbox->y + srcbox->height,
1713 0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
1714 } else {
1715 /* Draw the quad with the generic codepath. */
1716 int dst_z;
1717 for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1718 struct pipe_surface *old;
1719 float dst2src_scale = srcbox->depth / (float)dstbox->depth;
1720
1721 /* Scale Z properly if the blit is scaled.
1722 *
1723 * When downscaling, we want the coordinates centered, so that
1724 * mipmapping works for 3D textures. For example, when generating
1725 * a 4x4x4 level, this wouldn't average the pixels:
1726 *
1727 * src Z: 0 1 2 3 4 5 6 7
1728 * dst Z: 0 1 2 3
1729 *
1730 * Because the pixels are not centered below the pixels of the higher
1731 * level. Therefore, we want this:
1732 * src Z: 0 1 2 3 4 5 6 7
1733 * dst Z: 0 1 2 3
1734 *
1735 * dst_offset defines the offset needed for centering the pixels and
1736 * it works with any scaling (not just 2x).
1737 */
1738 float dst_offset = ((srcbox->depth - 1) -
1739 (dstbox->depth - 1) * dst2src_scale) * 0.5;
1740 float src_z = (dst_z + dst_offset) * dst2src_scale;
1741
1742 /* Set framebuffer state. */
1743 if (is_zsbuf) {
1744 fb_state.zsbuf = dst;
1745 } else {
1746 fb_state.cbufs[0] = dst;
1747 }
1748 pipe->set_framebuffer_state(pipe, &fb_state);
1749
1750 /* See if we need to blit a multisample or singlesample buffer. */
1751 if (src_samples == dst_samples && dst_samples > 1) {
1752 /* MSAA copy. */
1753 unsigned i, max_sample = dst_samples - 1;
1754
1755 for (i = 0; i <= max_sample; i++) {
1756 pipe->set_sample_mask(pipe, 1 << i);
1757 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1758 dstbox->x + dstbox->width,
1759 dstbox->y + dstbox->height,
1760 src, src_width0, src_height0,
1761 srcbox->x, srcbox->y,
1762 srcbox->x + srcbox->width,
1763 srcbox->y + srcbox->height,
1764 srcbox->z + src_z, i, uses_txf,
1765 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1766 }
1767 } else {
1768 /* Normal copy, MSAA upsampling, or MSAA resolve. */
1769 pipe->set_sample_mask(pipe, ~0);
1770 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1771 dstbox->x + dstbox->width,
1772 dstbox->y + dstbox->height,
1773 src, src_width0, src_height0,
1774 srcbox->x, srcbox->y,
1775 srcbox->x + srcbox->width,
1776 srcbox->y + srcbox->height,
1777 srcbox->z + src_z, 0, uses_txf,
1778 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1779 }
1780
1781 /* Get the next surface or (if this is the last iteration)
1782 * just unreference the last one. */
1783 old = dst;
1784 if (dst_z < dstbox->depth-1) {
1785 dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
1786 }
1787 if (dst_z) {
1788 pipe_surface_reference(&old, NULL);
1789 }
1790 }
1791 }
1792 }
1793
1794 void util_blitter_blit_generic(struct blitter_context *blitter,
1795 struct pipe_surface *dst,
1796 const struct pipe_box *dstbox,
1797 struct pipe_sampler_view *src,
1798 const struct pipe_box *srcbox,
1799 unsigned src_width0, unsigned src_height0,
1800 unsigned mask, unsigned filter,
1801 const struct pipe_scissor_state *scissor,
1802 bool alpha_blend)
1803 {
1804 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1805 struct pipe_context *pipe = ctx->base.pipe;
1806 enum pipe_texture_target src_target = src->target;
1807 unsigned src_samples = src->texture->nr_samples;
1808 unsigned dst_samples = dst->texture->nr_samples;
1809 bool has_depth, has_stencil, has_color;
1810 bool blit_stencil, blit_depth, blit_color;
1811 void *sampler_state;
1812 const struct util_format_description *src_desc =
1813 util_format_description(src->format);
1814 const struct util_format_description *dst_desc =
1815 util_format_description(dst->format);
1816
1817 has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS &&
1818 dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1819 has_depth = util_format_has_depth(src_desc) &&
1820 util_format_has_depth(dst_desc);
1821 has_stencil = util_format_has_stencil(src_desc) &&
1822 util_format_has_stencil(dst_desc);
1823
1824 blit_color = has_color && (mask & PIPE_MASK_RGBA);
1825 blit_depth = has_depth && (mask & PIPE_MASK_Z);
1826 blit_stencil = has_stencil && (mask & PIPE_MASK_S) &&
1827 ctx->has_stencil_export;
1828
1829 if (!blit_stencil && !blit_depth && !blit_color) {
1830 return;
1831 }
1832
1833 bool is_scaled = dstbox->width != abs(srcbox->width) ||
1834 dstbox->height != abs(srcbox->height);
1835
1836 if (blit_stencil || !is_scaled)
1837 filter = PIPE_TEX_FILTER_NEAREST;
1838
1839 bool use_txf = false;
1840
1841 /* Don't support scaled blits. The TXF shader uses F2I for rounding. */
1842 if (ctx->has_txf &&
1843 !is_scaled &&
1844 filter == PIPE_TEX_FILTER_NEAREST &&
1845 src->target != PIPE_TEXTURE_CUBE &&
1846 src->target != PIPE_TEXTURE_CUBE_ARRAY) {
1847 int src_width = u_minify(src_width0, src->u.tex.first_level);
1848 int src_height = u_minify(src_height0, src->u.tex.first_level);
1849 int src_depth = src->u.tex.last_layer + 1;
1850 struct pipe_box box = *srcbox;
1851
1852 /* Eliminate negative width/height/depth. */
1853 if (box.width < 0) {
1854 box.x += box.width;
1855 box.width *= -1;
1856 }
1857 if (box.height < 0) {
1858 box.y += box.height;
1859 box.height *= -1;
1860 }
1861 if (box.depth < 0) {
1862 box.z += box.depth;
1863 box.depth *= -1;
1864 }
1865
1866 /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */
1867 use_txf =
1868 box.x >= 0 && box.x < src_width &&
1869 box.y >= 0 && box.y < src_height &&
1870 box.z >= 0 && box.z < src_depth &&
1871 box.x + box.width > 0 && box.x + box.width <= src_width &&
1872 box.y + box.height > 0 && box.y + box.height <= src_height &&
1873 box.z + box.depth > 0 && box.z + box.depth <= src_depth;
1874 }
1875
1876 /* Check whether the states are properly saved. */
1877 util_blitter_set_running_flag(blitter);
1878 blitter_check_saved_vertex_states(ctx);
1879 blitter_check_saved_fragment_states(ctx);
1880 blitter_check_saved_textures(ctx);
1881 blitter_check_saved_fb_state(ctx);
1882 blitter_disable_render_cond(ctx);
1883
1884 if (blit_depth || blit_stencil) {
1885 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
1886
1887 if (blit_depth && blit_stencil) {
1888 pipe->bind_depth_stencil_alpha_state(pipe,
1889 ctx->dsa_write_depth_stencil);
1890 ctx->bind_fs_state(pipe,
1891 blitter_get_fs_texfetch_depthstencil(ctx, src_target,
1892 src_samples, use_txf));
1893 } else if (blit_depth) {
1894 pipe->bind_depth_stencil_alpha_state(pipe,
1895 ctx->dsa_write_depth_keep_stencil);
1896 ctx->bind_fs_state(pipe,
1897 blitter_get_fs_texfetch_depth(ctx, src_target,
1898 src_samples, use_txf));
1899 } else { /* is_stencil */
1900 pipe->bind_depth_stencil_alpha_state(pipe,
1901 ctx->dsa_keep_depth_write_stencil);
1902 ctx->bind_fs_state(pipe,
1903 blitter_get_fs_texfetch_stencil(ctx, src_target,
1904 src_samples, use_txf));
1905 }
1906
1907 } else {
1908 unsigned colormask = mask & PIPE_MASK_RGBA;
1909
1910 pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
1911 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1912 ctx->bind_fs_state(pipe,
1913 blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
1914 src_samples, dst_samples, filter,
1915 use_txf));
1916 }
1917
1918 /* Set the linear filter only for scaled color non-MSAA blits. */
1919 if (filter == PIPE_TEX_FILTER_LINEAR) {
1920 if (src_target == PIPE_TEXTURE_RECT) {
1921 sampler_state = ctx->sampler_state_rect_linear;
1922 } else {
1923 sampler_state = ctx->sampler_state_linear;
1924 }
1925 } else {
1926 if (src_target == PIPE_TEXTURE_RECT) {
1927 sampler_state = ctx->sampler_state_rect;
1928 } else {
1929 sampler_state = ctx->sampler_state;
1930 }
1931 }
1932
1933 /* Set samplers. */
1934 if (blit_depth && blit_stencil) {
1935 /* Setup two samplers, one for depth and the other one for stencil. */
1936 struct pipe_sampler_view templ;
1937 struct pipe_sampler_view *views[2];
1938 void *samplers[2] = {sampler_state, sampler_state};
1939
1940 templ = *src;
1941 templ.format = util_format_stencil_only(templ.format);
1942 assert(templ.format != PIPE_FORMAT_NONE);
1943
1944 views[0] = src;
1945 views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
1946
1947 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, views);
1948 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
1949
1950 pipe_sampler_view_reference(&views[1], NULL);
1951 } else if (blit_stencil) {
1952 /* Set a stencil-only sampler view for it not to sample depth instead. */
1953 struct pipe_sampler_view templ;
1954 struct pipe_sampler_view *view;
1955
1956 templ = *src;
1957 templ.format = util_format_stencil_only(templ.format);
1958 assert(templ.format != PIPE_FORMAT_NONE);
1959
1960 view = pipe->create_sampler_view(pipe, src->texture, &templ);
1961
1962 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &view);
1963 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
1964 0, 1, &sampler_state);
1965
1966 pipe_sampler_view_reference(&view, NULL);
1967 } else {
1968 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src);
1969 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
1970 0, 1, &sampler_state);
1971 }
1972
1973 if (scissor) {
1974 pipe->set_scissor_states(pipe, 0, 1, scissor);
1975 }
1976
1977 blitter_set_common_draw_rect_state(ctx, scissor != NULL);
1978
1979 do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
1980 srcbox, blit_depth || blit_stencil, use_txf);
1981
1982 util_blitter_restore_vertex_states(blitter);
1983 util_blitter_restore_fragment_states(blitter);
1984 util_blitter_restore_textures(blitter);
1985 util_blitter_restore_fb_state(blitter);
1986 if (scissor) {
1987 pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
1988 }
1989 util_blitter_restore_render_cond(blitter);
1990 util_blitter_unset_running_flag(blitter);
1991 }
1992
1993 void
1994 util_blitter_blit(struct blitter_context *blitter,
1995 const struct pipe_blit_info *info)
1996 {
1997 struct pipe_resource *dst = info->dst.resource;
1998 struct pipe_resource *src = info->src.resource;
1999 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2000 struct pipe_context *pipe = ctx->base.pipe;
2001 struct pipe_surface *dst_view, dst_templ;
2002 struct pipe_sampler_view src_templ, *src_view;
2003
2004 /* Initialize the surface. */
2005 util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
2006 info->dst.box.z);
2007 dst_templ.format = info->dst.format;
2008 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2009
2010 /* Initialize the sampler view. */
2011 util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level);
2012 src_templ.format = info->src.format;
2013 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2014
2015 /* Copy. */
2016 util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
2017 src_view, &info->src.box, src->width0, src->height0,
2018 info->mask, info->filter,
2019 info->scissor_enable ? &info->scissor : NULL,
2020 info->alpha_blend);
2021
2022 pipe_surface_reference(&dst_view, NULL);
2023 pipe_sampler_view_reference(&src_view, NULL);
2024 }
2025
2026 void util_blitter_generate_mipmap(struct blitter_context *blitter,
2027 struct pipe_resource *tex,
2028 enum pipe_format format,
2029 unsigned base_level, unsigned last_level,
2030 unsigned first_layer, unsigned last_layer)
2031 {
2032 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2033 struct pipe_context *pipe = ctx->base.pipe;
2034 struct pipe_surface dst_templ, *dst_view;
2035 struct pipe_sampler_view src_templ, *src_view;
2036 bool is_depth;
2037 void *sampler_state;
2038 const struct util_format_description *desc =
2039 util_format_description(format);
2040 unsigned src_level;
2041 unsigned target = tex->target;
2042
2043 if (ctx->cube_as_2darray &&
2044 (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY))
2045 target = PIPE_TEXTURE_2D_ARRAY;
2046
2047 assert(tex->nr_samples <= 1);
2048 assert(!util_format_has_stencil(desc));
2049
2050 is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
2051
2052 /* Check whether the states are properly saved. */
2053 util_blitter_set_running_flag(blitter);
2054 blitter_check_saved_vertex_states(ctx);
2055 blitter_check_saved_fragment_states(ctx);
2056 blitter_check_saved_textures(ctx);
2057 blitter_check_saved_fb_state(ctx);
2058 blitter_disable_render_cond(ctx);
2059
2060 /* Set states. */
2061 if (is_depth) {
2062 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2063 pipe->bind_depth_stencil_alpha_state(pipe,
2064 ctx->dsa_write_depth_keep_stencil);
2065 ctx->bind_fs_state(pipe,
2066 blitter_get_fs_texfetch_depth(ctx, target, 1, false));
2067 } else {
2068 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2069 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2070 ctx->bind_fs_state(pipe,
2071 blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
2072 1, 1, PIPE_TEX_FILTER_LINEAR, false));
2073 }
2074
2075 if (target == PIPE_TEXTURE_RECT) {
2076 sampler_state = ctx->sampler_state_rect_linear;
2077 } else {
2078 sampler_state = ctx->sampler_state_linear;
2079 }
2080 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2081 0, 1, &sampler_state);
2082
2083 blitter_set_common_draw_rect_state(ctx, false);
2084
2085 for (src_level = base_level; src_level < last_level; src_level++) {
2086 struct pipe_box dstbox = {0}, srcbox = {0};
2087 unsigned dst_level = src_level + 1;
2088
2089 dstbox.width = u_minify(tex->width0, dst_level);
2090 dstbox.height = u_minify(tex->height0, dst_level);
2091
2092 srcbox.width = u_minify(tex->width0, src_level);
2093 srcbox.height = u_minify(tex->height0, src_level);
2094
2095 if (target == PIPE_TEXTURE_3D) {
2096 dstbox.depth = util_num_layers(tex, dst_level);
2097 srcbox.depth = util_num_layers(tex, src_level);
2098 } else {
2099 dstbox.z = srcbox.z = first_layer;
2100 dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
2101 }
2102
2103 /* Initialize the surface. */
2104 util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
2105 first_layer);
2106 dst_templ.format = format;
2107 dst_view = pipe->create_surface(pipe, tex, &dst_templ);
2108
2109 /* Initialize the sampler view. */
2110 util_blitter_default_src_texture(blitter, &src_templ, tex, src_level);
2111 src_templ.format = format;
2112 src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
2113
2114 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &src_view);
2115
2116 do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
2117 &srcbox, is_depth, false);
2118
2119 pipe_surface_reference(&dst_view, NULL);
2120 pipe_sampler_view_reference(&src_view, NULL);
2121 }
2122
2123 util_blitter_restore_vertex_states(blitter);
2124 util_blitter_restore_fragment_states(blitter);
2125 util_blitter_restore_textures(blitter);
2126 util_blitter_restore_fb_state(blitter);
2127 util_blitter_restore_render_cond(blitter);
2128 util_blitter_unset_running_flag(blitter);
2129 }
2130
2131 /* Clear a region of a color surface to a constant value. */
2132 void util_blitter_clear_render_target(struct blitter_context *blitter,
2133 struct pipe_surface *dstsurf,
2134 const union pipe_color_union *color,
2135 unsigned dstx, unsigned dsty,
2136 unsigned width, unsigned height)
2137 {
2138 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2139 struct pipe_context *pipe = ctx->base.pipe;
2140 struct pipe_framebuffer_state fb_state;
2141 unsigned num_layers;
2142
2143 assert(dstsurf->texture);
2144 if (!dstsurf->texture)
2145 return;
2146
2147 /* check the saved state */
2148 util_blitter_set_running_flag(blitter);
2149 blitter_check_saved_vertex_states(ctx);
2150 blitter_check_saved_fragment_states(ctx);
2151 blitter_check_saved_fb_state(ctx);
2152 blitter_disable_render_cond(ctx);
2153
2154 /* bind states */
2155 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2156 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2157 bind_fs_write_one_cbuf(ctx);
2158
2159 /* set a framebuffer state */
2160 fb_state.width = dstsurf->width;
2161 fb_state.height = dstsurf->height;
2162 fb_state.nr_cbufs = 1;
2163 fb_state.cbufs[0] = dstsurf;
2164 fb_state.zsbuf = 0;
2165 pipe->set_framebuffer_state(pipe, &fb_state);
2166 pipe->set_sample_mask(pipe, ~0);
2167
2168 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2169
2170 union blitter_attrib attrib;
2171 memcpy(attrib.color, color->ui, sizeof(color->ui));
2172
2173 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2174 if (num_layers > 1 && ctx->has_layered) {
2175 blitter_set_common_draw_rect_state(ctx, false);
2176 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2177 dstx, dsty, dstx+width, dsty+height, 0,
2178 num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2179 } else {
2180 blitter_set_common_draw_rect_state(ctx, false);
2181 blitter->draw_rectangle(blitter, ctx->velem_state,
2182 get_vs_passthrough_pos_generic,
2183 dstx, dsty, dstx+width, dsty+height, 0,
2184 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2185 }
2186
2187 util_blitter_restore_vertex_states(blitter);
2188 util_blitter_restore_fragment_states(blitter);
2189 util_blitter_restore_fb_state(blitter);
2190 util_blitter_restore_render_cond(blitter);
2191 util_blitter_unset_running_flag(blitter);
2192 }
2193
2194 /* Clear a region of a depth stencil surface. */
2195 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2196 struct pipe_surface *dstsurf,
2197 unsigned clear_flags,
2198 double depth,
2199 unsigned stencil,
2200 unsigned dstx, unsigned dsty,
2201 unsigned width, unsigned height)
2202 {
2203 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2204 struct pipe_context *pipe = ctx->base.pipe;
2205 struct pipe_framebuffer_state fb_state;
2206 struct pipe_stencil_ref sr = { { 0 } };
2207 unsigned num_layers;
2208
2209 assert(dstsurf->texture);
2210 if (!dstsurf->texture)
2211 return;
2212
2213 /* check the saved state */
2214 util_blitter_set_running_flag(blitter);
2215 blitter_check_saved_vertex_states(ctx);
2216 blitter_check_saved_fragment_states(ctx);
2217 blitter_check_saved_fb_state(ctx);
2218 blitter_disable_render_cond(ctx);
2219
2220 /* bind states */
2221 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2222 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2223 sr.ref_value[0] = stencil & 0xff;
2224 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2225 pipe->set_stencil_ref(pipe, &sr);
2226 }
2227 else if (clear_flags & PIPE_CLEAR_DEPTH) {
2228 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2229 }
2230 else if (clear_flags & PIPE_CLEAR_STENCIL) {
2231 sr.ref_value[0] = stencil & 0xff;
2232 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2233 pipe->set_stencil_ref(pipe, &sr);
2234 }
2235 else
2236 /* hmm that should be illegal probably, or make it a no-op somewhere */
2237 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2238
2239 bind_fs_empty(ctx);
2240
2241 /* set a framebuffer state */
2242 fb_state.width = dstsurf->width;
2243 fb_state.height = dstsurf->height;
2244 fb_state.nr_cbufs = 0;
2245 fb_state.cbufs[0] = 0;
2246 fb_state.zsbuf = dstsurf;
2247 pipe->set_framebuffer_state(pipe, &fb_state);
2248 pipe->set_sample_mask(pipe, ~0);
2249
2250 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2251
2252 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2253 if (num_layers > 1 && ctx->has_layered) {
2254 blitter_set_common_draw_rect_state(ctx, false);
2255 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2256 dstx, dsty, dstx+width, dsty+height, depth,
2257 num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
2258 } else {
2259 blitter_set_common_draw_rect_state(ctx, false);
2260 blitter->draw_rectangle(blitter, ctx->velem_state,
2261 get_vs_passthrough_pos,
2262 dstx, dsty, dstx+width, dsty+height, depth, 1,
2263 UTIL_BLITTER_ATTRIB_NONE, NULL);
2264 }
2265
2266 util_blitter_restore_vertex_states(blitter);
2267 util_blitter_restore_fragment_states(blitter);
2268 util_blitter_restore_fb_state(blitter);
2269 util_blitter_restore_render_cond(blitter);
2270 util_blitter_unset_running_flag(blitter);
2271 }
2272
2273 /* draw a rectangle across a region using a custom dsa stage - for r600g */
2274 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2275 struct pipe_surface *zsurf,
2276 struct pipe_surface *cbsurf,
2277 unsigned sample_mask,
2278 void *dsa_stage, float depth)
2279 {
2280 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2281 struct pipe_context *pipe = ctx->base.pipe;
2282 struct pipe_framebuffer_state fb_state;
2283
2284 assert(zsurf->texture);
2285 if (!zsurf->texture)
2286 return;
2287
2288 /* check the saved state */
2289 util_blitter_set_running_flag(blitter);
2290 blitter_check_saved_vertex_states(ctx);
2291 blitter_check_saved_fragment_states(ctx);
2292 blitter_check_saved_fb_state(ctx);
2293 blitter_disable_render_cond(ctx);
2294
2295 /* bind states */
2296 pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2297 ctx->blend[0][0]);
2298 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2299 if (cbsurf)
2300 bind_fs_write_one_cbuf(ctx);
2301 else
2302 bind_fs_empty(ctx);
2303
2304 /* set a framebuffer state */
2305 fb_state.width = zsurf->width;
2306 fb_state.height = zsurf->height;
2307 fb_state.nr_cbufs = 1;
2308 if (cbsurf) {
2309 fb_state.cbufs[0] = cbsurf;
2310 fb_state.nr_cbufs = 1;
2311 } else {
2312 fb_state.cbufs[0] = NULL;
2313 fb_state.nr_cbufs = 0;
2314 }
2315 fb_state.zsbuf = zsurf;
2316 pipe->set_framebuffer_state(pipe, &fb_state);
2317 pipe->set_sample_mask(pipe, sample_mask);
2318
2319 blitter_set_common_draw_rect_state(ctx, false);
2320 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2321 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2322 0, 0, zsurf->width, zsurf->height, depth,
2323 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2324
2325 util_blitter_restore_vertex_states(blitter);
2326 util_blitter_restore_fragment_states(blitter);
2327 util_blitter_restore_fb_state(blitter);
2328 util_blitter_restore_render_cond(blitter);
2329 util_blitter_unset_running_flag(blitter);
2330 }
2331
2332 void util_blitter_copy_buffer(struct blitter_context *blitter,
2333 struct pipe_resource *dst,
2334 unsigned dstx,
2335 struct pipe_resource *src,
2336 unsigned srcx,
2337 unsigned size)
2338 {
2339 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2340 struct pipe_context *pipe = ctx->base.pipe;
2341 struct pipe_vertex_buffer vb;
2342 struct pipe_stream_output_target *so_target;
2343 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2344
2345 if (srcx >= src->width0 ||
2346 dstx >= dst->width0) {
2347 return;
2348 }
2349 if (srcx + size > src->width0) {
2350 size = src->width0 - srcx;
2351 }
2352 if (dstx + size > dst->width0) {
2353 size = dst->width0 - dstx;
2354 }
2355
2356 /* Drivers not capable of Stream Out should not call this function
2357 * in the first place. */
2358 assert(ctx->has_stream_out);
2359
2360 /* Some alignment is required. */
2361 if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
2362 !ctx->has_stream_out) {
2363 struct pipe_box box;
2364 u_box_1d(srcx, size, &box);
2365 util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
2366 return;
2367 }
2368
2369 util_blitter_set_running_flag(blitter);
2370 blitter_check_saved_vertex_states(ctx);
2371 blitter_disable_render_cond(ctx);
2372
2373 vb.is_user_buffer = false;
2374 vb.buffer.resource = src;
2375 vb.buffer_offset = srcx;
2376 vb.stride = 4;
2377
2378 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2379 pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
2380 bind_vs_pos_only(ctx, 1);
2381 if (ctx->has_geometry_shader)
2382 pipe->bind_gs_state(pipe, NULL);
2383 if (ctx->has_tessellation) {
2384 pipe->bind_tcs_state(pipe, NULL);
2385 pipe->bind_tes_state(pipe, NULL);
2386 }
2387 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2388
2389 so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
2390 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2391
2392 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2393
2394 util_blitter_restore_vertex_states(blitter);
2395 util_blitter_restore_render_cond(blitter);
2396 util_blitter_unset_running_flag(blitter);
2397 pipe_so_target_reference(&so_target, NULL);
2398 }
2399
2400 void util_blitter_clear_buffer(struct blitter_context *blitter,
2401 struct pipe_resource *dst,
2402 unsigned offset, unsigned size,
2403 unsigned num_channels,
2404 const union pipe_color_union *clear_value)
2405 {
2406 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2407 struct pipe_context *pipe = ctx->base.pipe;
2408 struct pipe_vertex_buffer vb = {0};
2409 struct pipe_stream_output_target *so_target = NULL;
2410 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2411
2412 assert(num_channels >= 1);
2413 assert(num_channels <= 4);
2414
2415 /* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE!
2416 *
2417 * R600 uses this to initialize texture resources, so width0 might not be
2418 * what you think it is.
2419 */
2420
2421 /* Streamout is required. */
2422 if (!ctx->has_stream_out) {
2423 assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2424 return;
2425 }
2426
2427 /* Some alignment is required. */
2428 if (offset % 4 != 0 || size % 4 != 0) {
2429 assert(!"Bad alignment in util_blitter_clear_buffer()");
2430 return;
2431 }
2432
2433 u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
2434 &vb.buffer_offset, &vb.buffer.resource);
2435 if (!vb.buffer.resource)
2436 goto out;
2437
2438 vb.stride = 0;
2439
2440 util_blitter_set_running_flag(blitter);
2441 blitter_check_saved_vertex_states(ctx);
2442 blitter_disable_render_cond(ctx);
2443
2444 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
2445 pipe->bind_vertex_elements_state(pipe,
2446 ctx->velem_state_readbuf[num_channels-1]);
2447 bind_vs_pos_only(ctx, num_channels);
2448 if (ctx->has_geometry_shader)
2449 pipe->bind_gs_state(pipe, NULL);
2450 if (ctx->has_tessellation) {
2451 pipe->bind_tcs_state(pipe, NULL);
2452 pipe->bind_tes_state(pipe, NULL);
2453 }
2454 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2455
2456 so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2457 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2458
2459 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2460
2461 out:
2462 util_blitter_restore_vertex_states(blitter);
2463 util_blitter_restore_render_cond(blitter);
2464 util_blitter_unset_running_flag(blitter);
2465 pipe_so_target_reference(&so_target, NULL);
2466 pipe_resource_reference(&vb.buffer.resource, NULL);
2467 }
2468
2469 /* probably radeon specific */
2470 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2471 struct pipe_resource *dst,
2472 unsigned dst_level,
2473 unsigned dst_layer,
2474 struct pipe_resource *src,
2475 unsigned src_layer,
2476 unsigned sample_mask,
2477 void *custom_blend,
2478 enum pipe_format format)
2479 {
2480 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2481 struct pipe_context *pipe = ctx->base.pipe;
2482 struct pipe_framebuffer_state fb_state;
2483 struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2484
2485 util_blitter_set_running_flag(blitter);
2486 blitter_check_saved_vertex_states(ctx);
2487 blitter_check_saved_fragment_states(ctx);
2488 blitter_disable_render_cond(ctx);
2489
2490 /* bind states */
2491 pipe->bind_blend_state(pipe, custom_blend);
2492 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2493 bind_fs_write_one_cbuf(ctx);
2494 pipe->set_sample_mask(pipe, sample_mask);
2495
2496 memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2497 surf_tmpl.format = format;
2498 surf_tmpl.u.tex.level = dst_level;
2499 surf_tmpl.u.tex.first_layer = dst_layer;
2500 surf_tmpl.u.tex.last_layer = dst_layer;
2501
2502 dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2503
2504 surf_tmpl.u.tex.level = 0;
2505 surf_tmpl.u.tex.first_layer = src_layer;
2506 surf_tmpl.u.tex.last_layer = src_layer;
2507
2508 srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2509
2510 /* set a framebuffer state */
2511 fb_state.width = src->width0;
2512 fb_state.height = src->height0;
2513 fb_state.nr_cbufs = 2;
2514 fb_state.cbufs[0] = srcsurf;
2515 fb_state.cbufs[1] = dstsurf;
2516 fb_state.zsbuf = NULL;
2517 pipe->set_framebuffer_state(pipe, &fb_state);
2518
2519 blitter_set_common_draw_rect_state(ctx, false);
2520 blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2521 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2522 0, 0, src->width0, src->height0,
2523 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2524 util_blitter_restore_fb_state(blitter);
2525 util_blitter_restore_vertex_states(blitter);
2526 util_blitter_restore_fragment_states(blitter);
2527 util_blitter_restore_render_cond(blitter);
2528 util_blitter_unset_running_flag(blitter);
2529
2530 pipe_surface_reference(&srcsurf, NULL);
2531 pipe_surface_reference(&dstsurf, NULL);
2532 }
2533
2534 void util_blitter_custom_color(struct blitter_context *blitter,
2535 struct pipe_surface *dstsurf,
2536 void *custom_blend)
2537 {
2538 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2539 struct pipe_context *pipe = ctx->base.pipe;
2540 struct pipe_framebuffer_state fb_state;
2541
2542 assert(dstsurf->texture);
2543 if (!dstsurf->texture)
2544 return;
2545
2546 /* check the saved state */
2547 util_blitter_set_running_flag(blitter);
2548 blitter_check_saved_vertex_states(ctx);
2549 blitter_check_saved_fragment_states(ctx);
2550 blitter_check_saved_fb_state(ctx);
2551 blitter_disable_render_cond(ctx);
2552
2553 /* bind states */
2554 pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2555 : ctx->blend[PIPE_MASK_RGBA][0]);
2556 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2557 bind_fs_write_one_cbuf(ctx);
2558 pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
2559
2560 /* set a framebuffer state */
2561 fb_state.width = dstsurf->width;
2562 fb_state.height = dstsurf->height;
2563 fb_state.nr_cbufs = 1;
2564 fb_state.cbufs[0] = dstsurf;
2565 fb_state.zsbuf = 0;
2566 pipe->set_framebuffer_state(pipe, &fb_state);
2567 pipe->set_sample_mask(pipe, ~0);
2568
2569 blitter_set_common_draw_rect_state(ctx, false);
2570 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2571 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2572 0, 0, dstsurf->width, dstsurf->height,
2573 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2574
2575 util_blitter_restore_vertex_states(blitter);
2576 util_blitter_restore_fragment_states(blitter);
2577 util_blitter_restore_fb_state(blitter);
2578 util_blitter_restore_render_cond(blitter);
2579 util_blitter_unset_running_flag(blitter);
2580 }
2581
2582 static void *get_custom_vs(struct blitter_context *blitter)
2583 {
2584 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2585
2586 return ctx->custom_vs;
2587 }
2588
2589 /**
2590 * Performs a custom blit to the destination surface, using the VS and FS
2591 * provided.
2592 *
2593 * Used by vc4 for the 8-bit linear-to-tiled blit.
2594 */
2595 void util_blitter_custom_shader(struct blitter_context *blitter,
2596 struct pipe_surface *dstsurf,
2597 void *custom_vs, void *custom_fs)
2598 {
2599 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2600 struct pipe_context *pipe = ctx->base.pipe;
2601 struct pipe_framebuffer_state fb_state;
2602
2603 ctx->custom_vs = custom_vs;
2604
2605 assert(dstsurf->texture);
2606 if (!dstsurf->texture)
2607 return;
2608
2609 /* check the saved state */
2610 util_blitter_set_running_flag(blitter);
2611 blitter_check_saved_vertex_states(ctx);
2612 blitter_check_saved_fragment_states(ctx);
2613 blitter_check_saved_fb_state(ctx);
2614 blitter_disable_render_cond(ctx);
2615
2616 /* bind states */
2617 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2618 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2619 pipe->bind_fs_state(pipe, custom_fs);
2620 pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1);
2621
2622 /* set a framebuffer state */
2623 fb_state.width = dstsurf->width;
2624 fb_state.height = dstsurf->height;
2625 fb_state.nr_cbufs = 1;
2626 fb_state.cbufs[0] = dstsurf;
2627 fb_state.zsbuf = 0;
2628 pipe->set_framebuffer_state(pipe, &fb_state);
2629 pipe->set_sample_mask(pipe, ~0);
2630
2631 blitter_set_common_draw_rect_state(ctx, false);
2632 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2633 blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs,
2634 0, 0, dstsurf->width, dstsurf->height,
2635 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2636
2637 util_blitter_restore_vertex_states(blitter);
2638 util_blitter_restore_fragment_states(blitter);
2639 util_blitter_restore_fb_state(blitter);
2640 util_blitter_restore_render_cond(blitter);
2641 util_blitter_unset_running_flag(blitter);
2642 }