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