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, 0, true,
637 &ctx->base.saved_vertex_buffer);
638 ctx->base.saved_vertex_buffer.buffer.resource = NULL;
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, 0, true,
788 ctx->base.saved_sampler_views);
789
790 /* Just clear them to NULL because set_sampler_views(take_ownership = true). */
791 for (i = 0; i < ctx->base.saved_num_sampler_views; i++)
792 ctx->base.saved_sampler_views[i] = NULL;
793
794 ctx->base.saved_num_sampler_views = ~0;
795 }
796
util_blitter_restore_constant_buffer_state(struct blitter_context * blitter)797 void util_blitter_restore_constant_buffer_state(struct blitter_context *blitter)
798 {
799 struct pipe_context *pipe = blitter->pipe;
800
801 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
802 true, &blitter->saved_fs_constant_buffer);
803 blitter->saved_fs_constant_buffer.buffer = NULL;
804 }
805
blitter_set_rectangle(struct blitter_context_priv * ctx,int x1,int y1,int x2,int y2,float depth)806 static void blitter_set_rectangle(struct blitter_context_priv *ctx,
807 int x1, int y1, int x2, int y2,
808 float depth)
809 {
810 /* set vertex positions */
811 ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/
812 ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/
813
814 ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/
815 ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/
816
817 ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/
818 ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/
819
820 ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/
821 ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/
822
823 /* viewport */
824 struct pipe_viewport_state viewport;
825 viewport.scale[0] = 0.5f * ctx->dst_width;
826 viewport.scale[1] = 0.5f * ctx->dst_height;
827 viewport.scale[2] = 0.0f;
828 viewport.translate[0] = 0.5f * ctx->dst_width;
829 viewport.translate[1] = 0.5f * ctx->dst_height;
830 viewport.translate[2] = depth;
831 viewport.swizzle_x = PIPE_VIEWPORT_SWIZZLE_POSITIVE_X;
832 viewport.swizzle_y = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Y;
833 viewport.swizzle_z = PIPE_VIEWPORT_SWIZZLE_POSITIVE_Z;
834 viewport.swizzle_w = PIPE_VIEWPORT_SWIZZLE_POSITIVE_W;
835 ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &viewport);
836 }
837
blitter_set_clear_color(struct blitter_context_priv * ctx,const float color[4])838 static void blitter_set_clear_color(struct blitter_context_priv *ctx,
839 const float color[4])
840 {
841 int i;
842
843 if (color) {
844 for (i = 0; i < 4; i++)
845 memcpy(&ctx->vertices[i][1][0], color, sizeof(uint32_t) * 4);
846 } else {
847 for (i = 0; i < 4; i++)
848 memset(&ctx->vertices[i][1][0], 0, sizeof(uint32_t) * 4);
849 }
850 }
851
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)852 static void get_texcoords(struct pipe_sampler_view *src,
853 unsigned src_width0, unsigned src_height0,
854 int x1, int y1, int x2, int y2,
855 float layer, unsigned sample,
856 bool uses_txf, union blitter_attrib *out)
857 {
858 unsigned level = src->u.tex.first_level;
859 bool normalized = !uses_txf &&
860 src->target != PIPE_TEXTURE_RECT &&
861 src->texture->nr_samples <= 1;
862
863 if (normalized) {
864 out->texcoord.x1 = x1 / (float)u_minify(src_width0, level);
865 out->texcoord.y1 = y1 / (float)u_minify(src_height0, level);
866 out->texcoord.x2 = x2 / (float)u_minify(src_width0, level);
867 out->texcoord.y2 = y2 / (float)u_minify(src_height0, level);
868 } else {
869 out->texcoord.x1 = x1;
870 out->texcoord.y1 = y1;
871 out->texcoord.x2 = x2;
872 out->texcoord.y2 = y2;
873 }
874
875 out->texcoord.z = 0;
876 out->texcoord.w = 0;
877
878 /* Set the layer. */
879 switch (src->target) {
880 case PIPE_TEXTURE_3D:
881 {
882 float r = layer;
883
884 if (!uses_txf)
885 r /= u_minify(src->texture->depth0, src->u.tex.first_level);
886
887 out->texcoord.z = r;
888 }
889 break;
890
891 case PIPE_TEXTURE_1D_ARRAY:
892 out->texcoord.y1 = out->texcoord.y2 = layer;
893 break;
894
895 case PIPE_TEXTURE_2D_ARRAY:
896 out->texcoord.z = layer;
897 out->texcoord.w = sample;
898 break;
899
900 case PIPE_TEXTURE_CUBE_ARRAY:
901 out->texcoord.w = (unsigned)layer / 6;
902 break;
903
904 case PIPE_TEXTURE_2D:
905 out->texcoord.w = sample;
906 break;
907
908 default:;
909 }
910 }
911
blitter_set_dst_dimensions(struct blitter_context_priv * ctx,unsigned width,unsigned height)912 static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
913 unsigned width, unsigned height)
914 {
915 ctx->dst_width = width;
916 ctx->dst_height = height;
917 }
918
set_texcoords_in_vertices(const union blitter_attrib * attrib,float * out,unsigned stride)919 static void set_texcoords_in_vertices(const union blitter_attrib *attrib,
920 float *out, unsigned stride)
921 {
922 out[0] = attrib->texcoord.x1;
923 out[1] = attrib->texcoord.y1;
924 out += stride;
925 out[0] = attrib->texcoord.x2;
926 out[1] = attrib->texcoord.y1;
927 out += stride;
928 out[0] = attrib->texcoord.x2;
929 out[1] = attrib->texcoord.y2;
930 out += stride;
931 out[0] = attrib->texcoord.x1;
932 out[1] = attrib->texcoord.y2;
933 }
934
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)935 static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
936 enum pipe_format src_format,
937 enum pipe_format dst_format,
938 enum pipe_texture_target target,
939 unsigned src_nr_samples,
940 unsigned dst_nr_samples,
941 unsigned filter,
942 bool use_txf)
943 {
944 struct pipe_context *pipe = ctx->base.pipe;
945 enum tgsi_texture_type tgsi_tex =
946 util_pipe_tex_to_tgsi_tex(target, src_nr_samples);
947 enum tgsi_return_type stype;
948 enum tgsi_return_type dtype;
949 unsigned type;
950
951 assert(target < PIPE_MAX_TEXTURE_TYPES);
952
953 if (util_format_is_pure_uint(src_format)) {
954 stype = TGSI_RETURN_TYPE_UINT;
955 if (util_format_is_pure_uint(dst_format)) {
956 dtype = TGSI_RETURN_TYPE_UINT;
957 type = 0;
958 } else {
959 assert(util_format_is_pure_sint(dst_format));
960 dtype = TGSI_RETURN_TYPE_SINT;
961 type = 1;
962 }
963 } else if (util_format_is_pure_sint(src_format)) {
964 stype = TGSI_RETURN_TYPE_SINT;
965 if (util_format_is_pure_sint(dst_format)) {
966 dtype = TGSI_RETURN_TYPE_SINT;
967 type = 2;
968 } else {
969 assert(util_format_is_pure_uint(dst_format));
970 dtype = TGSI_RETURN_TYPE_UINT;
971 type = 3;
972 }
973 } else {
974 assert(!util_format_is_pure_uint(dst_format) &&
975 !util_format_is_pure_sint(dst_format));
976 dtype = stype = TGSI_RETURN_TYPE_FLOAT;
977 type = 4;
978 }
979
980 if (src_nr_samples > 1) {
981 void **shader;
982
983 /* OpenGL requires that integer textures just copy 1 sample instead
984 * of averaging.
985 */
986 if (dst_nr_samples <= 1 &&
987 stype != TGSI_RETURN_TYPE_UINT &&
988 stype != TGSI_RETURN_TYPE_SINT) {
989 /* The destination has one sample, so we'll do color resolve. */
990 unsigned index = GET_MSAA_RESOLVE_FS_IDX(src_nr_samples);
991
992 assert(filter < 2);
993
994 shader = &ctx->fs_resolve[target][index][filter];
995
996 if (!*shader) {
997 assert(!ctx->cached_all_shaders);
998 if (filter == PIPE_TEX_FILTER_LINEAR) {
999 *shader = util_make_fs_msaa_resolve_bilinear(pipe, tgsi_tex,
1000 src_nr_samples,
1001 stype);
1002 }
1003 else {
1004 *shader = util_make_fs_msaa_resolve(pipe, tgsi_tex,
1005 src_nr_samples,
1006 stype);
1007 }
1008 }
1009 }
1010 else {
1011 /* The destination has multiple samples, we'll do
1012 * an MSAA->MSAA copy.
1013 */
1014 shader = &ctx->fs_texfetch_col_msaa[type][target];
1015
1016 /* Create the fragment shader on-demand. */
1017 if (!*shader) {
1018 assert(!ctx->cached_all_shaders);
1019 *shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex, stype, dtype);
1020 }
1021 }
1022
1023 return *shader;
1024 } else {
1025 void **shader;
1026
1027 if (use_txf)
1028 shader = &ctx->fs_texfetch_col[type][target][1];
1029 else
1030 shader = &ctx->fs_texfetch_col[type][target][0];
1031
1032 /* Create the fragment shader on-demand. */
1033 if (!*shader) {
1034 assert(!ctx->cached_all_shaders);
1035 *shader = util_make_fragment_tex_shader(pipe, tgsi_tex,
1036 TGSI_INTERPOLATE_LINEAR,
1037 stype, dtype,
1038 ctx->has_tex_lz, use_txf);
1039 }
1040
1041 return *shader;
1042 }
1043 }
1044
1045 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)1046 void *blitter_get_fs_pack_color_zs(struct blitter_context_priv *ctx,
1047 enum pipe_texture_target target,
1048 unsigned nr_samples,
1049 enum pipe_format zs_format,
1050 bool dst_is_color)
1051 {
1052 struct pipe_context *pipe = ctx->base.pipe;
1053 enum tgsi_texture_type tgsi_tex =
1054 util_pipe_tex_to_tgsi_tex(target, nr_samples);
1055 int format_index = zs_format == PIPE_FORMAT_Z24_UNORM_S8_UINT ? 0 :
1056 zs_format == PIPE_FORMAT_S8_UINT_Z24_UNORM ? 1 :
1057 zs_format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ? 2 :
1058 zs_format == PIPE_FORMAT_Z24X8_UNORM ? 3 :
1059 zs_format == PIPE_FORMAT_X8Z24_UNORM ? 4 : -1;
1060
1061 if (format_index == -1) {
1062 assert(0);
1063 return NULL;
1064 }
1065
1066 /* The first 5 shaders pack ZS to color, the last 5 shaders unpack color
1067 * to ZS.
1068 */
1069 if (dst_is_color)
1070 format_index += 5;
1071
1072 void **shader = &ctx->fs_pack_color_zs[tgsi_tex][format_index];
1073
1074 /* Create the fragment shader on-demand. */
1075 if (!*shader) {
1076 assert(!ctx->cached_all_shaders);
1077 *shader = util_make_fs_pack_color_zs(pipe, tgsi_tex, zs_format,
1078 dst_is_color);
1079 }
1080 return *shader;
1081 }
1082
1083 static inline
blitter_get_fs_texfetch_depth(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1084 void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
1085 enum pipe_texture_target target,
1086 unsigned nr_samples,
1087 bool use_txf)
1088 {
1089 struct pipe_context *pipe = ctx->base.pipe;
1090
1091 assert(target < PIPE_MAX_TEXTURE_TYPES);
1092
1093 if (nr_samples > 1) {
1094 void **shader = &ctx->fs_texfetch_depth_msaa[target];
1095
1096 /* Create the fragment shader on-demand. */
1097 if (!*shader) {
1098 enum tgsi_texture_type tgsi_tex;
1099 assert(!ctx->cached_all_shaders);
1100 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1101 *shader = util_make_fs_blit_msaa_depth(pipe, tgsi_tex);
1102 }
1103
1104 return *shader;
1105 } else {
1106 void **shader;
1107
1108 if (use_txf)
1109 shader = &ctx->fs_texfetch_depth[target][1];
1110 else
1111 shader = &ctx->fs_texfetch_depth[target][0];
1112
1113 /* Create the fragment shader on-demand. */
1114 if (!*shader) {
1115 enum tgsi_texture_type tgsi_tex;
1116 assert(!ctx->cached_all_shaders);
1117 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1118 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_Z, tgsi_tex,
1119 ctx->has_tex_lz, use_txf);
1120 }
1121
1122 return *shader;
1123 }
1124 }
1125
1126 static inline
blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1127 void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx,
1128 enum pipe_texture_target target,
1129 unsigned nr_samples,
1130 bool use_txf)
1131 {
1132 struct pipe_context *pipe = ctx->base.pipe;
1133
1134 assert(target < PIPE_MAX_TEXTURE_TYPES);
1135
1136 if (nr_samples > 1) {
1137 void **shader = &ctx->fs_texfetch_depthstencil_msaa[target];
1138
1139 /* Create the fragment shader on-demand. */
1140 if (!*shader) {
1141 enum tgsi_texture_type tgsi_tex;
1142 assert(!ctx->cached_all_shaders);
1143 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1144 *shader = util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex);
1145 }
1146
1147 return *shader;
1148 } else {
1149 void **shader;
1150
1151 if (use_txf)
1152 shader = &ctx->fs_texfetch_depthstencil[target][1];
1153 else
1154 shader = &ctx->fs_texfetch_depthstencil[target][0];
1155
1156 /* Create the fragment shader on-demand. */
1157 if (!*shader) {
1158 enum tgsi_texture_type tgsi_tex;
1159 assert(!ctx->cached_all_shaders);
1160 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1161 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_ZS, tgsi_tex,
1162 ctx->has_tex_lz, use_txf);
1163 }
1164
1165 return *shader;
1166 }
1167 }
1168
1169 static inline
blitter_get_fs_texfetch_stencil(struct blitter_context_priv * ctx,enum pipe_texture_target target,unsigned nr_samples,bool use_txf)1170 void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx,
1171 enum pipe_texture_target target,
1172 unsigned nr_samples,
1173 bool use_txf)
1174 {
1175 struct pipe_context *pipe = ctx->base.pipe;
1176
1177 assert(target < PIPE_MAX_TEXTURE_TYPES);
1178
1179 if (nr_samples > 1) {
1180 void **shader = &ctx->fs_texfetch_stencil_msaa[target];
1181
1182 /* Create the fragment shader on-demand. */
1183 if (!*shader) {
1184 enum tgsi_texture_type tgsi_tex;
1185 assert(!ctx->cached_all_shaders);
1186 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, nr_samples);
1187 *shader = util_make_fs_blit_msaa_stencil(pipe, tgsi_tex);
1188 }
1189
1190 return *shader;
1191 } else {
1192 void **shader;
1193
1194 if (use_txf)
1195 shader = &ctx->fs_texfetch_stencil[target][1];
1196 else
1197 shader = &ctx->fs_texfetch_stencil[target][0];
1198
1199 /* Create the fragment shader on-demand. */
1200 if (!*shader) {
1201 enum tgsi_texture_type tgsi_tex;
1202 assert(!ctx->cached_all_shaders);
1203 tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0);
1204 *shader = util_make_fs_blit_zs(pipe, PIPE_MASK_S, tgsi_tex,
1205 ctx->has_tex_lz, use_txf);
1206 }
1207
1208 return *shader;
1209 }
1210 }
1211
1212
1213 /**
1214 * Generate and save all fragment shaders that we will ever need for
1215 * blitting. Drivers which use the 'draw' fallbacks will typically use
1216 * this to make sure we generate/use shaders that don't go through the
1217 * draw module's wrapper functions.
1218 */
util_blitter_cache_all_shaders(struct blitter_context * blitter)1219 void util_blitter_cache_all_shaders(struct blitter_context *blitter)
1220 {
1221 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1222 struct pipe_context *pipe = blitter->pipe;
1223 struct pipe_screen *screen = pipe->screen;
1224 unsigned samples, j, f, target, max_samples, use_txf;
1225 bool has_arraytex, has_cubearraytex;
1226
1227 max_samples = ctx->has_texture_multisample ? 2 : 1;
1228 has_arraytex = screen->get_param(screen,
1229 PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0;
1230 has_cubearraytex = screen->get_param(screen,
1231 PIPE_CAP_CUBE_MAP_ARRAY) != 0;
1232
1233 /* It only matters if i <= 1 or > 1. */
1234 for (samples = 1; samples <= max_samples; samples++) {
1235 for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) {
1236 for (use_txf = 0; use_txf <= ctx->has_txf; use_txf++) {
1237 if (!has_arraytex &&
1238 (target == PIPE_TEXTURE_1D_ARRAY ||
1239 target == PIPE_TEXTURE_2D_ARRAY)) {
1240 continue;
1241 }
1242 if (!has_cubearraytex &&
1243 (target == PIPE_TEXTURE_CUBE_ARRAY))
1244 continue;
1245
1246 if (samples > 1 &&
1247 (target != PIPE_TEXTURE_2D &&
1248 target != PIPE_TEXTURE_2D_ARRAY))
1249 continue;
1250
1251 if (samples > 1 && use_txf)
1252 continue; /* TXF is the only option, use_txf has no effect */
1253
1254 /* If samples == 1, the shaders read one texel. If samples >= 1,
1255 * they read one sample.
1256 */
1257 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1258 PIPE_FORMAT_R32_FLOAT, target,
1259 samples, samples, 0, use_txf);
1260 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1261 PIPE_FORMAT_R32_UINT, target,
1262 samples, samples, 0, use_txf);
1263 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1264 PIPE_FORMAT_R32_SINT, target,
1265 samples, samples, 0, use_txf);
1266 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1267 PIPE_FORMAT_R32_SINT, target,
1268 samples, samples, 0, use_txf);
1269 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1270 PIPE_FORMAT_R32_UINT, target,
1271 samples, samples, 0, use_txf);
1272 blitter_get_fs_texfetch_depth(ctx, target, samples, use_txf);
1273 if (ctx->has_stencil_export) {
1274 blitter_get_fs_texfetch_depthstencil(ctx, target, samples, use_txf);
1275 blitter_get_fs_texfetch_stencil(ctx, target, samples, use_txf);
1276 }
1277
1278 if (samples == 1)
1279 continue;
1280
1281 /* MSAA resolve shaders. */
1282 for (j = 2; j < 32; j++) {
1283 if (!screen->is_format_supported(screen, PIPE_FORMAT_R32_FLOAT,
1284 target, j, j,
1285 PIPE_BIND_SAMPLER_VIEW)) {
1286 continue;
1287 }
1288
1289 for (f = 0; f < 2; f++) {
1290 if (f != PIPE_TEX_FILTER_NEAREST && use_txf)
1291 continue;
1292
1293 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_FLOAT,
1294 PIPE_FORMAT_R32_FLOAT, target,
1295 j, 1, f, use_txf);
1296 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_UINT,
1297 PIPE_FORMAT_R32_UINT, target,
1298 j, 1, f, use_txf);
1299 blitter_get_fs_texfetch_col(ctx, PIPE_FORMAT_R32_SINT,
1300 PIPE_FORMAT_R32_SINT, target,
1301 j, 1, f, use_txf);
1302 }
1303 }
1304 }
1305 }
1306 }
1307
1308 ctx->fs_empty = util_make_empty_fragment_shader(pipe);
1309
1310 ctx->fs_write_one_cbuf =
1311 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1312 TGSI_INTERPOLATE_CONSTANT, false);
1313
1314 ctx->fs_write_all_cbufs =
1315 util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC,
1316 TGSI_INTERPOLATE_CONSTANT, true);
1317
1318 ctx->cached_all_shaders = true;
1319 }
1320
blitter_set_common_draw_rect_state(struct blitter_context_priv * ctx,bool scissor,bool msaa)1321 static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx,
1322 bool scissor, bool msaa)
1323 {
1324 struct pipe_context *pipe = ctx->base.pipe;
1325
1326 if (ctx->base.saved_num_window_rectangles)
1327 pipe->set_window_rectangles(pipe, false, 0, NULL);
1328
1329 pipe->bind_rasterizer_state(pipe, ctx->rs_state[scissor][msaa]);
1330
1331 if (ctx->has_geometry_shader)
1332 pipe->bind_gs_state(pipe, NULL);
1333 if (ctx->has_tessellation) {
1334 pipe->bind_tcs_state(pipe, NULL);
1335 pipe->bind_tes_state(pipe, NULL);
1336 }
1337 if (ctx->has_stream_out)
1338 pipe->set_stream_output_targets(pipe, 0, NULL, NULL);
1339 }
1340
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)1341 static void blitter_draw(struct blitter_context_priv *ctx,
1342 void *vertex_elements_cso,
1343 blitter_get_vs_func get_vs,
1344 int x1, int y1, int x2, int y2, float depth,
1345 unsigned num_instances)
1346 {
1347 struct pipe_context *pipe = ctx->base.pipe;
1348 struct pipe_vertex_buffer vb = {0};
1349
1350 blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
1351
1352 vb.stride = 8 * sizeof(float);
1353
1354 u_upload_data(pipe->stream_uploader, 0, sizeof(ctx->vertices), 4, ctx->vertices,
1355 &vb.buffer_offset, &vb.buffer.resource);
1356 if (!vb.buffer.resource)
1357 return;
1358 u_upload_unmap(pipe->stream_uploader);
1359
1360 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb);
1361 pipe->bind_vertex_elements_state(pipe, vertex_elements_cso);
1362 pipe->bind_vs_state(pipe, get_vs(&ctx->base));
1363
1364 if (ctx->base.use_index_buffer) {
1365 /* Note that for V3D,
1366 * dEQP-GLES3.functional.fbo.blit.rect.nearest_consistency_* require
1367 * that the last vert of the two tris be the same.
1368 */
1369 static uint8_t indices[6] = { 0, 1, 2, 0, 3, 2 };
1370 util_draw_elements_instanced(pipe, indices, 1, 0,
1371 PIPE_PRIM_TRIANGLES, 0, 6,
1372 0, num_instances);
1373 } else {
1374 util_draw_arrays_instanced(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4,
1375 0, num_instances);
1376 }
1377 pipe_resource_reference(&vb.buffer.resource, NULL);
1378 }
1379
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)1380 void util_blitter_draw_rectangle(struct blitter_context *blitter,
1381 void *vertex_elements_cso,
1382 blitter_get_vs_func get_vs,
1383 int x1, int y1, int x2, int y2,
1384 float depth, unsigned num_instances,
1385 enum blitter_attrib_type type,
1386 const union blitter_attrib *attrib)
1387 {
1388 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1389 unsigned i;
1390
1391 switch (type) {
1392 case UTIL_BLITTER_ATTRIB_COLOR:
1393 blitter_set_clear_color(ctx, attrib->color);
1394 break;
1395
1396 case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW:
1397 for (i = 0; i < 4; i++) {
1398 ctx->vertices[i][1][2] = attrib->texcoord.z;
1399 ctx->vertices[i][1][3] = attrib->texcoord.w;
1400 }
1401 FALLTHROUGH;
1402 case UTIL_BLITTER_ATTRIB_TEXCOORD_XY:
1403 set_texcoords_in_vertices(attrib, &ctx->vertices[0][1][0], 8);
1404 break;
1405
1406 default:;
1407 }
1408
1409 blitter_draw(ctx, vertex_elements_cso, get_vs, x1, y1, x2, y2, depth,
1410 num_instances);
1411 }
1412
get_clear_blend_state(struct blitter_context_priv * ctx,unsigned clear_buffers)1413 static void *get_clear_blend_state(struct blitter_context_priv *ctx,
1414 unsigned clear_buffers)
1415 {
1416 struct pipe_context *pipe = ctx->base.pipe;
1417 int index;
1418
1419 clear_buffers &= PIPE_CLEAR_COLOR;
1420
1421 /* Return an existing blend state. */
1422 if (!clear_buffers)
1423 return ctx->blend[0][0];
1424
1425 index = GET_CLEAR_BLEND_STATE_IDX(clear_buffers);
1426
1427 if (ctx->blend_clear[index])
1428 return ctx->blend_clear[index];
1429
1430 /* Create a new one. */
1431 {
1432 struct pipe_blend_state blend = {0};
1433 unsigned i;
1434
1435 blend.independent_blend_enable = 1;
1436
1437 for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
1438 if (clear_buffers & (PIPE_CLEAR_COLOR0 << i)) {
1439 blend.rt[i].colormask = PIPE_MASK_RGBA;
1440 blend.max_rt = i;
1441 }
1442 }
1443
1444 ctx->blend_clear[index] = pipe->create_blend_state(pipe, &blend);
1445 }
1446 return ctx->blend_clear[index];
1447 }
1448
util_blitter_common_clear_setup(struct blitter_context * blitter,unsigned width,unsigned height,unsigned clear_buffers,void * custom_blend,void * custom_dsa)1449 void util_blitter_common_clear_setup(struct blitter_context *blitter,
1450 unsigned width, unsigned height,
1451 unsigned clear_buffers,
1452 void *custom_blend, void *custom_dsa)
1453 {
1454 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1455 struct pipe_context *pipe = ctx->base.pipe;
1456
1457 util_blitter_set_running_flag(blitter);
1458 blitter_check_saved_vertex_states(ctx);
1459 blitter_check_saved_fragment_states(ctx);
1460 blitter_disable_render_cond(ctx);
1461
1462 /* bind states */
1463 if (custom_blend) {
1464 pipe->bind_blend_state(pipe, custom_blend);
1465 } else {
1466 pipe->bind_blend_state(pipe, get_clear_blend_state(ctx, clear_buffers));
1467 }
1468
1469 if (custom_dsa) {
1470 pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
1471 } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
1472 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
1473 } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
1474 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
1475 } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
1476 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
1477 } else {
1478 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
1479 }
1480
1481 pipe->set_sample_mask(pipe, ~0);
1482 blitter_set_dst_dimensions(ctx, width, height);
1483 }
1484
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)1485 static void util_blitter_clear_custom(struct blitter_context *blitter,
1486 unsigned width, unsigned height,
1487 unsigned num_layers,
1488 unsigned clear_buffers,
1489 const union pipe_color_union *color,
1490 double depth, unsigned stencil,
1491 void *custom_blend, void *custom_dsa,
1492 bool msaa)
1493 {
1494 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1495 struct pipe_context *pipe = ctx->base.pipe;
1496 struct pipe_stencil_ref sr = { { 0 } };
1497
1498 assert(ctx->has_layered || num_layers <= 1);
1499
1500 util_blitter_common_clear_setup(blitter, width, height, clear_buffers,
1501 custom_blend, custom_dsa);
1502
1503 sr.ref_value[0] = stencil & 0xff;
1504 pipe->set_stencil_ref(pipe, sr);
1505
1506 union blitter_attrib attrib;
1507 memcpy(attrib.color, color->ui, sizeof(color->ui));
1508
1509 bool pass_generic = (clear_buffers & PIPE_CLEAR_COLOR) != 0;
1510 enum blitter_attrib_type type = pass_generic ? UTIL_BLITTER_ATTRIB_COLOR :
1511 UTIL_BLITTER_ATTRIB_NONE;
1512
1513 if (pass_generic)
1514 bind_fs_write_all_cbufs(ctx);
1515 else
1516 bind_fs_empty(ctx);
1517
1518 if (num_layers > 1 && ctx->has_layered) {
1519 blitter_get_vs_func get_vs = get_vs_layered;
1520
1521 blitter_set_common_draw_rect_state(ctx, false, msaa);
1522 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1523 0, 0, width, height,
1524 (float) depth, num_layers, type, &attrib);
1525 } else {
1526 blitter_get_vs_func get_vs;
1527
1528 if (pass_generic)
1529 get_vs = get_vs_passthrough_pos_generic;
1530 else
1531 get_vs = get_vs_passthrough_pos;
1532
1533 blitter_set_common_draw_rect_state(ctx, false, msaa);
1534 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs,
1535 0, 0, width, height,
1536 (float) depth, 1, type, &attrib);
1537 }
1538
1539 util_blitter_restore_vertex_states(blitter);
1540 util_blitter_restore_fragment_states(blitter);
1541 util_blitter_restore_render_cond(blitter);
1542 util_blitter_unset_running_flag(blitter);
1543 }
1544
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)1545 void util_blitter_clear(struct blitter_context *blitter,
1546 unsigned width, unsigned height, unsigned num_layers,
1547 unsigned clear_buffers,
1548 const union pipe_color_union *color,
1549 double depth, unsigned stencil,
1550 bool msaa)
1551 {
1552 util_blitter_clear_custom(blitter, width, height, num_layers,
1553 clear_buffers, color, depth, stencil,
1554 NULL, NULL, msaa);
1555 }
1556
util_blitter_custom_clear_depth(struct blitter_context * blitter,unsigned width,unsigned height,double depth,void * custom_dsa)1557 void util_blitter_custom_clear_depth(struct blitter_context *blitter,
1558 unsigned width, unsigned height,
1559 double depth, void *custom_dsa)
1560 {
1561 static const union pipe_color_union color;
1562 util_blitter_clear_custom(blitter, width, height, 0, 0, &color, depth, 0,
1563 NULL, custom_dsa, false);
1564 }
1565
util_blitter_default_dst_texture(struct pipe_surface * dst_templ,struct pipe_resource * dst,unsigned dstlevel,unsigned dstz)1566 void util_blitter_default_dst_texture(struct pipe_surface *dst_templ,
1567 struct pipe_resource *dst,
1568 unsigned dstlevel,
1569 unsigned dstz)
1570 {
1571 memset(dst_templ, 0, sizeof(*dst_templ));
1572 dst_templ->format = util_format_linear(dst->format);
1573 dst_templ->u.tex.level = dstlevel;
1574 dst_templ->u.tex.first_layer = dstz;
1575 dst_templ->u.tex.last_layer = dstz;
1576 }
1577
1578 static struct pipe_surface *
util_blitter_get_next_surface_layer(struct pipe_context * pipe,struct pipe_surface * surf)1579 util_blitter_get_next_surface_layer(struct pipe_context *pipe,
1580 struct pipe_surface *surf)
1581 {
1582 struct pipe_surface dst_templ;
1583
1584 memset(&dst_templ, 0, sizeof(dst_templ));
1585 dst_templ.format = surf->format;
1586 dst_templ.u.tex.level = surf->u.tex.level;
1587 dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1;
1588 dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1;
1589
1590 return pipe->create_surface(pipe, surf->texture, &dst_templ);
1591 }
1592
util_blitter_default_src_texture(struct blitter_context * blitter,struct pipe_sampler_view * src_templ,struct pipe_resource * src,unsigned srclevel)1593 void util_blitter_default_src_texture(struct blitter_context *blitter,
1594 struct pipe_sampler_view *src_templ,
1595 struct pipe_resource *src,
1596 unsigned srclevel)
1597 {
1598 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1599
1600 memset(src_templ, 0, sizeof(*src_templ));
1601
1602 if (ctx->cube_as_2darray &&
1603 (src->target == PIPE_TEXTURE_CUBE ||
1604 src->target == PIPE_TEXTURE_CUBE_ARRAY))
1605 src_templ->target = PIPE_TEXTURE_2D_ARRAY;
1606 else
1607 src_templ->target = src->target;
1608
1609 src_templ->format = util_format_linear(src->format);
1610 src_templ->u.tex.first_level = srclevel;
1611 src_templ->u.tex.last_level = srclevel;
1612 src_templ->u.tex.first_layer = 0;
1613 src_templ->u.tex.last_layer =
1614 src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1
1615 : (unsigned)(src->array_size - 1);
1616 src_templ->swizzle_r = PIPE_SWIZZLE_X;
1617 src_templ->swizzle_g = PIPE_SWIZZLE_Y;
1618 src_templ->swizzle_b = PIPE_SWIZZLE_Z;
1619 src_templ->swizzle_a = PIPE_SWIZZLE_W;
1620 }
1621
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)1622 static bool is_blit_generic_supported(struct blitter_context *blitter,
1623 const struct pipe_resource *dst,
1624 enum pipe_format dst_format,
1625 const struct pipe_resource *src,
1626 enum pipe_format src_format,
1627 unsigned mask)
1628 {
1629 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1630 struct pipe_screen *screen = ctx->base.pipe->screen;
1631
1632 if (dst) {
1633 unsigned bind;
1634 const struct util_format_description *desc =
1635 util_format_description(dst_format);
1636 bool dst_has_stencil = util_format_has_stencil(desc);
1637
1638 /* Stencil export must be supported for stencil copy. */
1639 if ((mask & PIPE_MASK_S) && dst_has_stencil &&
1640 !ctx->has_stencil_export) {
1641 return false;
1642 }
1643
1644 if (dst_has_stencil || util_format_has_depth(desc))
1645 bind = PIPE_BIND_DEPTH_STENCIL;
1646 else
1647 bind = PIPE_BIND_RENDER_TARGET;
1648
1649 if (!screen->is_format_supported(screen, dst_format, dst->target,
1650 dst->nr_samples, dst->nr_storage_samples,
1651 bind)) {
1652 return false;
1653 }
1654 }
1655
1656 if (src) {
1657 if (src->nr_samples > 1 && !ctx->has_texture_multisample) {
1658 return false;
1659 }
1660
1661 if (!screen->is_format_supported(screen, src_format, src->target,
1662 src->nr_samples, src->nr_storage_samples,
1663 PIPE_BIND_SAMPLER_VIEW)) {
1664 return false;
1665 }
1666
1667 /* Check stencil sampler support for stencil copy. */
1668 if (mask & PIPE_MASK_S) {
1669 if (util_format_has_stencil(util_format_description(src_format))) {
1670 enum pipe_format stencil_format =
1671 util_format_stencil_only(src_format);
1672 assert(stencil_format != PIPE_FORMAT_NONE);
1673
1674 if (stencil_format != src_format &&
1675 !screen->is_format_supported(screen, stencil_format,
1676 src->target, src->nr_samples,
1677 src->nr_storage_samples,
1678 PIPE_BIND_SAMPLER_VIEW)) {
1679 return false;
1680 }
1681 }
1682 }
1683 }
1684
1685 return true;
1686 }
1687
util_blitter_is_copy_supported(struct blitter_context * blitter,const struct pipe_resource * dst,const struct pipe_resource * src)1688 bool util_blitter_is_copy_supported(struct blitter_context *blitter,
1689 const struct pipe_resource *dst,
1690 const struct pipe_resource *src)
1691 {
1692 return is_blit_generic_supported(blitter, dst, dst->format,
1693 src, src->format, PIPE_MASK_RGBAZS);
1694 }
1695
util_blitter_is_blit_supported(struct blitter_context * blitter,const struct pipe_blit_info * info)1696 bool util_blitter_is_blit_supported(struct blitter_context *blitter,
1697 const struct pipe_blit_info *info)
1698 {
1699 return is_blit_generic_supported(blitter,
1700 info->dst.resource, info->dst.format,
1701 info->src.resource, info->src.format,
1702 info->mask);
1703 }
1704
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)1705 void util_blitter_copy_texture(struct blitter_context *blitter,
1706 struct pipe_resource *dst,
1707 unsigned dst_level,
1708 unsigned dstx, unsigned dsty, unsigned dstz,
1709 struct pipe_resource *src,
1710 unsigned src_level,
1711 const struct pipe_box *srcbox)
1712 {
1713 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1714 struct pipe_context *pipe = ctx->base.pipe;
1715 struct pipe_surface *dst_view, dst_templ;
1716 struct pipe_sampler_view src_templ, *src_view;
1717 struct pipe_box dstbox;
1718
1719 assert(dst && src);
1720 assert(src->target < PIPE_MAX_TEXTURE_TYPES);
1721
1722 u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height),
1723 abs(srcbox->depth), &dstbox);
1724
1725 /* Initialize the surface. */
1726 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz);
1727 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
1728
1729 /* Initialize the sampler view. */
1730 util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
1731 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
1732
1733 /* Copy. */
1734 util_blitter_blit_generic(blitter, dst_view, &dstbox,
1735 src_view, srcbox, src->width0, src->height0,
1736 PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL,
1737 false, false);
1738
1739 pipe_surface_reference(&dst_view, NULL);
1740 pipe_sampler_view_reference(&src_view, NULL);
1741 }
1742
1743 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)1744 blitter_draw_tex(struct blitter_context_priv *ctx,
1745 int dst_x1, int dst_y1, int dst_x2, int dst_y2,
1746 struct pipe_sampler_view *src,
1747 unsigned src_width0, unsigned src_height0,
1748 int src_x1, int src_y1, int src_x2, int src_y2,
1749 float layer, unsigned sample,
1750 bool uses_txf, enum blitter_attrib_type type)
1751 {
1752 union blitter_attrib coord;
1753 blitter_get_vs_func get_vs = get_vs_passthrough_pos_generic;
1754
1755 get_texcoords(src, src_width0, src_height0,
1756 src_x1, src_y1, src_x2, src_y2, layer, sample,
1757 uses_txf, &coord);
1758
1759 if (src->target == PIPE_TEXTURE_CUBE ||
1760 src->target == PIPE_TEXTURE_CUBE_ARRAY) {
1761 float face_coord[4][2];
1762
1763 set_texcoords_in_vertices(&coord, &face_coord[0][0], 2);
1764 util_map_texcoords2d_onto_cubemap((unsigned)layer % 6,
1765 /* pointer, stride in floats */
1766 &face_coord[0][0], 2,
1767 &ctx->vertices[0][1][0], 8,
1768 false);
1769 for (unsigned i = 0; i < 4; i++)
1770 ctx->vertices[i][1][3] = coord.texcoord.w;
1771
1772 /* Cubemaps don't use draw_rectangle. */
1773 blitter_draw(ctx, ctx->velem_state, get_vs,
1774 dst_x1, dst_y1, dst_x2, dst_y2, 0, 1);
1775 } else {
1776 ctx->base.draw_rectangle(&ctx->base, ctx->velem_state, get_vs,
1777 dst_x1, dst_y1, dst_x2, dst_y2,
1778 0, 1, type, &coord);
1779 }
1780 }
1781
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,bool sample0_only)1782 static void do_blits(struct blitter_context_priv *ctx,
1783 struct pipe_surface *dst,
1784 const struct pipe_box *dstbox,
1785 struct pipe_sampler_view *src,
1786 unsigned src_width0,
1787 unsigned src_height0,
1788 const struct pipe_box *srcbox,
1789 bool is_zsbuf,
1790 bool uses_txf, bool sample0_only)
1791 {
1792 struct pipe_context *pipe = ctx->base.pipe;
1793 unsigned src_samples = src->texture->nr_samples;
1794 unsigned dst_samples = dst->texture->nr_samples;
1795 enum pipe_texture_target src_target = src->target;
1796 struct pipe_framebuffer_state fb_state = {0};
1797
1798 /* Initialize framebuffer state. */
1799 fb_state.width = dst->width;
1800 fb_state.height = dst->height;
1801 fb_state.nr_cbufs = is_zsbuf ? 0 : 1;
1802
1803 blitter_set_dst_dimensions(ctx, fb_state.width, fb_state.height);
1804
1805 if ((src_target == PIPE_TEXTURE_1D ||
1806 src_target == PIPE_TEXTURE_2D ||
1807 src_target == PIPE_TEXTURE_RECT) &&
1808 src_samples <= 1) {
1809 /* Set framebuffer state. */
1810 if (is_zsbuf) {
1811 fb_state.zsbuf = dst;
1812 } else {
1813 fb_state.cbufs[0] = dst;
1814 }
1815 pipe->set_framebuffer_state(pipe, &fb_state);
1816
1817 /* Draw. */
1818 pipe->set_sample_mask(pipe, ~0);
1819 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1820 dstbox->x + dstbox->width,
1821 dstbox->y + dstbox->height,
1822 src, src_width0, src_height0, srcbox->x, srcbox->y,
1823 srcbox->x + srcbox->width, srcbox->y + srcbox->height,
1824 0, 0, uses_txf, UTIL_BLITTER_ATTRIB_TEXCOORD_XY);
1825 } else {
1826 /* Draw the quad with the generic codepath. */
1827 int dst_z;
1828 for (dst_z = 0; dst_z < dstbox->depth; dst_z++) {
1829 struct pipe_surface *old;
1830 bool flipped = (srcbox->depth < 0);
1831 float depth_center_offset = 0.0;
1832 int src_depth = abs(srcbox->depth);
1833 float src_z_step = src_depth / (float)dstbox->depth;
1834
1835 /* Scale Z properly if the blit is scaled.
1836 *
1837 * When downscaling, we want the coordinates centered, so that
1838 * mipmapping works for 3D textures. For example, when generating
1839 * a 4x4x4 level, this wouldn't average the pixels:
1840 *
1841 * src Z: 0 1 2 3 4 5 6 7
1842 * dst Z: 0 1 2 3
1843 *
1844 * Because the pixels are not centered below the pixels of the higher
1845 * level. Therefore, we want this:
1846 * src Z: 0 1 2 3 4 5 6 7
1847 * dst Z: 0 1 2 3
1848 *
1849 * This calculation is taken from the radv driver.
1850 */
1851 if (src_target == PIPE_TEXTURE_3D)
1852 depth_center_offset = 0.5 / dstbox->depth * src_depth;
1853
1854 if (flipped) {
1855 src_z_step *= - 1;
1856 depth_center_offset *= -1;
1857 }
1858
1859 float src_z = dst_z * src_z_step + depth_center_offset;
1860
1861 /* Set framebuffer state. */
1862 if (is_zsbuf) {
1863 fb_state.zsbuf = dst;
1864 } else {
1865 fb_state.cbufs[0] = dst;
1866 }
1867 pipe->set_framebuffer_state(pipe, &fb_state);
1868
1869 /* See if we need to blit a multisample or singlesample buffer. */
1870 if (sample0_only || (src_samples == dst_samples && dst_samples > 1)) {
1871 /* MSAA copy. */
1872 unsigned i, max_sample = sample0_only ? 0 : dst_samples - 1;
1873
1874 for (i = 0; i <= max_sample; i++) {
1875 pipe->set_sample_mask(pipe, 1 << i);
1876 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1877 dstbox->x + dstbox->width,
1878 dstbox->y + dstbox->height,
1879 src, src_width0, src_height0,
1880 srcbox->x, srcbox->y,
1881 srcbox->x + srcbox->width,
1882 srcbox->y + srcbox->height,
1883 srcbox->z + src_z, i, uses_txf,
1884 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1885 }
1886 } else {
1887 /* Normal copy, MSAA upsampling, or MSAA resolve. */
1888 pipe->set_sample_mask(pipe, ~0);
1889 blitter_draw_tex(ctx, dstbox->x, dstbox->y,
1890 dstbox->x + dstbox->width,
1891 dstbox->y + dstbox->height,
1892 src, src_width0, src_height0,
1893 srcbox->x, srcbox->y,
1894 srcbox->x + srcbox->width,
1895 srcbox->y + srcbox->height,
1896 srcbox->z + src_z, 0, uses_txf,
1897 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW);
1898 }
1899
1900 /* Get the next surface or (if this is the last iteration)
1901 * just unreference the last one. */
1902 old = dst;
1903 if (dst_z < dstbox->depth-1) {
1904 dst = util_blitter_get_next_surface_layer(ctx->base.pipe, dst);
1905 }
1906 if (dst_z) {
1907 pipe_surface_reference(&old, NULL);
1908 }
1909 }
1910 }
1911 }
1912
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,bool sample0_only)1913 void util_blitter_blit_generic(struct blitter_context *blitter,
1914 struct pipe_surface *dst,
1915 const struct pipe_box *dstbox,
1916 struct pipe_sampler_view *src,
1917 const struct pipe_box *srcbox,
1918 unsigned src_width0, unsigned src_height0,
1919 unsigned mask, unsigned filter,
1920 const struct pipe_scissor_state *scissor,
1921 bool alpha_blend, bool sample0_only)
1922 {
1923 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
1924 struct pipe_context *pipe = ctx->base.pipe;
1925 enum pipe_texture_target src_target = src->target;
1926 unsigned src_samples = src->texture->nr_samples;
1927 unsigned dst_samples = dst->texture->nr_samples;
1928 void *sampler_state;
1929 const struct util_format_description *src_desc =
1930 util_format_description(src->format);
1931 const struct util_format_description *dst_desc =
1932 util_format_description(dst->format);
1933
1934 bool src_has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1935 bool src_has_depth = util_format_has_depth(src_desc);
1936 bool src_has_stencil = util_format_has_stencil(src_desc);
1937
1938 bool dst_has_color = mask & PIPE_MASK_RGBA &&
1939 dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS;
1940 bool dst_has_depth = mask & PIPE_MASK_Z &&
1941 util_format_has_depth(dst_desc);
1942 bool dst_has_stencil = ctx->has_stencil_export &&
1943 mask & PIPE_MASK_S &&
1944 util_format_has_stencil(dst_desc);
1945
1946 /* Return if there is nothing to do. */
1947 if (!dst_has_color && !dst_has_depth && !dst_has_stencil) {
1948 return;
1949 }
1950
1951 bool is_scaled = dstbox->width != abs(srcbox->width) ||
1952 dstbox->height != abs(srcbox->height);
1953
1954 if (src_has_stencil || !is_scaled)
1955 filter = PIPE_TEX_FILTER_NEAREST;
1956
1957 bool use_txf = false;
1958
1959 /* Don't support scaled blits. The TXF shader uses F2I for rounding. */
1960 if (ctx->has_txf &&
1961 !is_scaled &&
1962 filter == PIPE_TEX_FILTER_NEAREST &&
1963 src->target != PIPE_TEXTURE_CUBE &&
1964 src->target != PIPE_TEXTURE_CUBE_ARRAY) {
1965 int src_width = u_minify(src_width0, src->u.tex.first_level);
1966 int src_height = u_minify(src_height0, src->u.tex.first_level);
1967 int src_depth = src->u.tex.last_layer + 1;
1968 struct pipe_box box = *srcbox;
1969
1970 /* Eliminate negative width/height/depth. */
1971 if (box.width < 0) {
1972 box.x += box.width;
1973 box.width *= -1;
1974 }
1975 if (box.height < 0) {
1976 box.y += box.height;
1977 box.height *= -1;
1978 }
1979 if (box.depth < 0) {
1980 box.z += box.depth;
1981 box.depth *= -1;
1982 }
1983
1984 /* See if srcbox is in bounds. TXF doesn't clamp the coordinates. */
1985 use_txf =
1986 box.x >= 0 && box.x < src_width &&
1987 box.y >= 0 && box.y < src_height &&
1988 box.z >= 0 && box.z < src_depth &&
1989 box.x + box.width > 0 && box.x + box.width <= src_width &&
1990 box.y + box.height > 0 && box.y + box.height <= src_height &&
1991 box.z + box.depth > 0 && box.z + box.depth <= src_depth;
1992 }
1993
1994 /* Check whether the states are properly saved. */
1995 util_blitter_set_running_flag(blitter);
1996 blitter_check_saved_vertex_states(ctx);
1997 blitter_check_saved_fragment_states(ctx);
1998 blitter_check_saved_textures(ctx);
1999 blitter_check_saved_fb_state(ctx);
2000 blitter_disable_render_cond(ctx);
2001
2002 /* Blend, DSA, fragment shader. */
2003 if (dst_has_depth && dst_has_stencil) {
2004 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2005 pipe->bind_depth_stencil_alpha_state(pipe,
2006 ctx->dsa_write_depth_stencil);
2007 if (src_has_color) {
2008 assert(use_txf);
2009 ctx->bind_fs_state(pipe,
2010 blitter_get_fs_pack_color_zs(ctx, src_target,
2011 src_samples, dst->format, false));
2012 } else {
2013 ctx->bind_fs_state(pipe,
2014 blitter_get_fs_texfetch_depthstencil(ctx, src_target,
2015 src_samples, use_txf));
2016 }
2017 } else if (dst_has_depth) {
2018 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2019 pipe->bind_depth_stencil_alpha_state(pipe,
2020 ctx->dsa_write_depth_keep_stencil);
2021 if (src_has_color &&
2022 (src->format == PIPE_FORMAT_R32_UINT ||
2023 src->format == PIPE_FORMAT_R32G32_UINT)) {
2024 assert(use_txf);
2025 ctx->bind_fs_state(pipe,
2026 blitter_get_fs_pack_color_zs(ctx, src_target,
2027 src_samples, dst->format, false));
2028 } else {
2029 ctx->bind_fs_state(pipe,
2030 blitter_get_fs_texfetch_depth(ctx, src_target,
2031 src_samples, use_txf));
2032 }
2033 } else if (dst_has_stencil) {
2034 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2035 pipe->bind_depth_stencil_alpha_state(pipe,
2036 ctx->dsa_keep_depth_write_stencil);
2037
2038 assert(src_has_stencil); /* unpacking from color is unsupported */
2039 ctx->bind_fs_state(pipe,
2040 blitter_get_fs_texfetch_stencil(ctx, src_target,
2041 src_samples, use_txf));
2042 } else {
2043 unsigned colormask = mask & PIPE_MASK_RGBA;
2044
2045 pipe->bind_blend_state(pipe, ctx->blend[colormask][alpha_blend]);
2046 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2047
2048 if (src_has_depth &&
2049 (dst->format == PIPE_FORMAT_R32_UINT ||
2050 dst->format == PIPE_FORMAT_R32G32_UINT)) {
2051 assert(use_txf);
2052 ctx->bind_fs_state(pipe,
2053 blitter_get_fs_pack_color_zs(ctx, src_target,
2054 src_samples, src->format, true));
2055 } else {
2056 ctx->bind_fs_state(pipe,
2057 blitter_get_fs_texfetch_col(ctx, src->format, dst->format, src_target,
2058 src_samples, dst_samples, filter,
2059 use_txf));
2060 }
2061 }
2062
2063 /* Set the linear filter only for scaled color non-MSAA blits. */
2064 if (filter == PIPE_TEX_FILTER_LINEAR) {
2065 if (src_target == PIPE_TEXTURE_RECT) {
2066 sampler_state = ctx->sampler_state_rect_linear;
2067 } else {
2068 sampler_state = ctx->sampler_state_linear;
2069 }
2070 } else {
2071 if (src_target == PIPE_TEXTURE_RECT) {
2072 sampler_state = ctx->sampler_state_rect;
2073 } else {
2074 sampler_state = ctx->sampler_state;
2075 }
2076 }
2077
2078 /* Set samplers. */
2079 if (src_has_depth && src_has_stencil &&
2080 (dst_has_color || (dst_has_depth && dst_has_stencil))) {
2081 /* Setup two samplers, one for depth and the other one for stencil. */
2082 struct pipe_sampler_view templ;
2083 struct pipe_sampler_view *views[2];
2084 void *samplers[2] = {sampler_state, sampler_state};
2085
2086 templ = *src;
2087 templ.format = util_format_stencil_only(templ.format);
2088 assert(templ.format != PIPE_FORMAT_NONE);
2089
2090 views[0] = src;
2091 views[1] = pipe->create_sampler_view(pipe, src->texture, &templ);
2092
2093 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 2, 0, false, views);
2094 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 2, samplers);
2095
2096 pipe_sampler_view_reference(&views[1], NULL);
2097 } else if (src_has_stencil && dst_has_stencil) {
2098 /* Set a stencil-only sampler view for it not to sample depth instead. */
2099 struct pipe_sampler_view templ;
2100 struct pipe_sampler_view *view;
2101
2102 templ = *src;
2103 templ.format = util_format_stencil_only(templ.format);
2104 assert(templ.format != PIPE_FORMAT_NONE);
2105
2106 view = pipe->create_sampler_view(pipe, src->texture, &templ);
2107
2108 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &view);
2109 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2110 0, 1, &sampler_state);
2111
2112 pipe_sampler_view_reference(&view, NULL);
2113 } else {
2114 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src);
2115 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2116 0, 1, &sampler_state);
2117 }
2118
2119 if (scissor) {
2120 pipe->set_scissor_states(pipe, 0, 1, scissor);
2121 }
2122
2123 blitter_set_common_draw_rect_state(ctx, scissor != NULL, dst_samples > 1);
2124
2125 do_blits(ctx, dst, dstbox, src, src_width0, src_height0,
2126 srcbox, dst_has_depth || dst_has_stencil, use_txf, sample0_only);
2127
2128 util_blitter_restore_vertex_states(blitter);
2129 util_blitter_restore_fragment_states(blitter);
2130 util_blitter_restore_textures(blitter);
2131 util_blitter_restore_fb_state(blitter);
2132 if (scissor) {
2133 pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2134 }
2135 util_blitter_restore_render_cond(blitter);
2136 util_blitter_unset_running_flag(blitter);
2137 }
2138
2139 void
util_blitter_blit(struct blitter_context * blitter,const struct pipe_blit_info * info)2140 util_blitter_blit(struct blitter_context *blitter,
2141 const struct pipe_blit_info *info)
2142 {
2143 struct pipe_resource *dst = info->dst.resource;
2144 struct pipe_resource *src = info->src.resource;
2145 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2146 struct pipe_context *pipe = ctx->base.pipe;
2147 struct pipe_surface *dst_view, dst_templ;
2148 struct pipe_sampler_view src_templ, *src_view;
2149
2150 /* Initialize the surface. */
2151 util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level,
2152 info->dst.box.z);
2153 dst_templ.format = info->dst.format;
2154 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2155
2156 /* Initialize the sampler view. */
2157 util_blitter_default_src_texture(blitter, &src_templ, src, info->src.level);
2158 src_templ.format = info->src.format;
2159 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2160
2161 /* Copy. */
2162 util_blitter_blit_generic(blitter, dst_view, &info->dst.box,
2163 src_view, &info->src.box, src->width0, src->height0,
2164 info->mask, info->filter,
2165 info->scissor_enable ? &info->scissor : NULL,
2166 info->alpha_blend, info->sample0_only);
2167
2168 pipe_surface_reference(&dst_view, NULL);
2169 pipe_sampler_view_reference(&src_view, NULL);
2170 }
2171
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)2172 void util_blitter_generate_mipmap(struct blitter_context *blitter,
2173 struct pipe_resource *tex,
2174 enum pipe_format format,
2175 unsigned base_level, unsigned last_level,
2176 unsigned first_layer, unsigned last_layer)
2177 {
2178 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2179 struct pipe_context *pipe = ctx->base.pipe;
2180 struct pipe_surface dst_templ, *dst_view;
2181 struct pipe_sampler_view src_templ, *src_view;
2182 bool is_depth;
2183 void *sampler_state;
2184 const struct util_format_description *desc =
2185 util_format_description(format);
2186 unsigned src_level;
2187 unsigned target = tex->target;
2188
2189 if (ctx->cube_as_2darray &&
2190 (target == PIPE_TEXTURE_CUBE || target == PIPE_TEXTURE_CUBE_ARRAY))
2191 target = PIPE_TEXTURE_2D_ARRAY;
2192
2193 assert(tex->nr_samples <= 1);
2194 /* Disallow stencil formats without depth. */
2195 assert(!util_format_has_stencil(desc) || util_format_has_depth(desc));
2196
2197 is_depth = desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS;
2198
2199 /* Check whether the states are properly saved. */
2200 util_blitter_set_running_flag(blitter);
2201 blitter_check_saved_vertex_states(ctx);
2202 blitter_check_saved_fragment_states(ctx);
2203 blitter_check_saved_textures(ctx);
2204 blitter_check_saved_fb_state(ctx);
2205 blitter_disable_render_cond(ctx);
2206
2207 /* Set states. */
2208 if (is_depth) {
2209 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2210 pipe->bind_depth_stencil_alpha_state(pipe,
2211 ctx->dsa_write_depth_keep_stencil);
2212 ctx->bind_fs_state(pipe,
2213 blitter_get_fs_texfetch_depth(ctx, target, 1, false));
2214 } else {
2215 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2216 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2217 ctx->bind_fs_state(pipe,
2218 blitter_get_fs_texfetch_col(ctx, tex->format, tex->format, target,
2219 1, 1, PIPE_TEX_FILTER_LINEAR, false));
2220 }
2221
2222 if (target == PIPE_TEXTURE_RECT) {
2223 sampler_state = ctx->sampler_state_rect_linear;
2224 } else {
2225 sampler_state = ctx->sampler_state_linear;
2226 }
2227 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT,
2228 0, 1, &sampler_state);
2229
2230 blitter_set_common_draw_rect_state(ctx, false, false);
2231
2232 for (src_level = base_level; src_level < last_level; src_level++) {
2233 struct pipe_box dstbox = {0}, srcbox = {0};
2234 unsigned dst_level = src_level + 1;
2235
2236 dstbox.width = u_minify(tex->width0, dst_level);
2237 dstbox.height = u_minify(tex->height0, dst_level);
2238
2239 srcbox.width = u_minify(tex->width0, src_level);
2240 srcbox.height = u_minify(tex->height0, src_level);
2241
2242 if (target == PIPE_TEXTURE_3D) {
2243 dstbox.depth = util_num_layers(tex, dst_level);
2244 srcbox.depth = util_num_layers(tex, src_level);
2245 } else {
2246 dstbox.z = srcbox.z = first_layer;
2247 dstbox.depth = srcbox.depth = last_layer - first_layer + 1;
2248 }
2249
2250 /* Initialize the surface. */
2251 util_blitter_default_dst_texture(&dst_templ, tex, dst_level,
2252 first_layer);
2253 dst_templ.format = format;
2254 dst_view = pipe->create_surface(pipe, tex, &dst_templ);
2255
2256 /* Initialize the sampler view. */
2257 util_blitter_default_src_texture(blitter, &src_templ, tex, src_level);
2258 src_templ.format = format;
2259 src_view = pipe->create_sampler_view(pipe, tex, &src_templ);
2260
2261 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2262
2263 do_blits(ctx, dst_view, &dstbox, src_view, tex->width0, tex->height0,
2264 &srcbox, is_depth, false, false);
2265
2266 pipe_surface_reference(&dst_view, NULL);
2267 pipe_sampler_view_reference(&src_view, NULL);
2268 }
2269
2270 util_blitter_restore_vertex_states(blitter);
2271 util_blitter_restore_fragment_states(blitter);
2272 util_blitter_restore_textures(blitter);
2273 util_blitter_restore_fb_state(blitter);
2274 util_blitter_restore_render_cond(blitter);
2275 util_blitter_unset_running_flag(blitter);
2276 }
2277
2278 /* 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)2279 void util_blitter_clear_render_target(struct blitter_context *blitter,
2280 struct pipe_surface *dstsurf,
2281 const union pipe_color_union *color,
2282 unsigned dstx, unsigned dsty,
2283 unsigned width, unsigned height)
2284 {
2285 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2286 struct pipe_context *pipe = ctx->base.pipe;
2287 struct pipe_framebuffer_state fb_state;
2288 bool msaa;
2289 unsigned num_layers;
2290
2291 assert(dstsurf->texture);
2292 if (!dstsurf->texture)
2293 return;
2294
2295 /* check the saved state */
2296 util_blitter_set_running_flag(blitter);
2297 blitter_check_saved_vertex_states(ctx);
2298 blitter_check_saved_fragment_states(ctx);
2299 blitter_check_saved_fb_state(ctx);
2300 blitter_disable_render_cond(ctx);
2301
2302 /* bind states */
2303 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2304 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2305 bind_fs_write_one_cbuf(ctx);
2306
2307 /* set a framebuffer state */
2308 fb_state.width = dstsurf->width;
2309 fb_state.height = dstsurf->height;
2310 fb_state.nr_cbufs = 1;
2311 fb_state.cbufs[0] = dstsurf;
2312 fb_state.zsbuf = 0;
2313 pipe->set_framebuffer_state(pipe, &fb_state);
2314 pipe->set_sample_mask(pipe, ~0);
2315 msaa = util_framebuffer_get_num_samples(&fb_state) > 1;
2316
2317 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2318
2319 union blitter_attrib attrib;
2320 memcpy(attrib.color, color->ui, sizeof(color->ui));
2321
2322 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2323 if (num_layers > 1 && ctx->has_layered) {
2324 blitter_set_common_draw_rect_state(ctx, false, msaa);
2325 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2326 dstx, dsty, dstx+width, dsty+height, 0,
2327 num_layers, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2328 } else {
2329 blitter_set_common_draw_rect_state(ctx, false, msaa);
2330 blitter->draw_rectangle(blitter, ctx->velem_state,
2331 get_vs_passthrough_pos_generic,
2332 dstx, dsty, dstx+width, dsty+height, 0,
2333 1, UTIL_BLITTER_ATTRIB_COLOR, &attrib);
2334 }
2335
2336 util_blitter_restore_vertex_states(blitter);
2337 util_blitter_restore_fragment_states(blitter);
2338 util_blitter_restore_fb_state(blitter);
2339 util_blitter_restore_render_cond(blitter);
2340 util_blitter_unset_running_flag(blitter);
2341 }
2342
2343 /* 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)2344 void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
2345 struct pipe_surface *dstsurf,
2346 unsigned clear_flags,
2347 double depth,
2348 unsigned stencil,
2349 unsigned dstx, unsigned dsty,
2350 unsigned width, unsigned height)
2351 {
2352 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2353 struct pipe_context *pipe = ctx->base.pipe;
2354 struct pipe_framebuffer_state fb_state;
2355 struct pipe_stencil_ref sr = { { 0 } };
2356 unsigned num_layers;
2357
2358 assert(dstsurf->texture);
2359 if (!dstsurf->texture)
2360 return;
2361
2362 /* check the saved state */
2363 util_blitter_set_running_flag(blitter);
2364 blitter_check_saved_vertex_states(ctx);
2365 blitter_check_saved_fragment_states(ctx);
2366 blitter_check_saved_fb_state(ctx);
2367 blitter_disable_render_cond(ctx);
2368
2369 /* bind states */
2370 pipe->bind_blend_state(pipe, ctx->blend[0][0]);
2371 if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
2372 sr.ref_value[0] = stencil & 0xff;
2373 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
2374 pipe->set_stencil_ref(pipe, sr);
2375 }
2376 else if (clear_flags & PIPE_CLEAR_DEPTH) {
2377 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
2378 }
2379 else if (clear_flags & PIPE_CLEAR_STENCIL) {
2380 sr.ref_value[0] = stencil & 0xff;
2381 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
2382 pipe->set_stencil_ref(pipe, sr);
2383 }
2384 else
2385 /* hmm that should be illegal probably, or make it a no-op somewhere */
2386 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2387
2388 bind_fs_empty(ctx);
2389
2390 /* set a framebuffer state */
2391 fb_state.width = dstsurf->width;
2392 fb_state.height = dstsurf->height;
2393 fb_state.nr_cbufs = 0;
2394 fb_state.cbufs[0] = 0;
2395 fb_state.zsbuf = dstsurf;
2396 pipe->set_framebuffer_state(pipe, &fb_state);
2397 pipe->set_sample_mask(pipe, ~0);
2398
2399 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2400
2401 num_layers = dstsurf->u.tex.last_layer - dstsurf->u.tex.first_layer + 1;
2402 if (num_layers > 1 && ctx->has_layered) {
2403 blitter_set_common_draw_rect_state(ctx, false, false);
2404 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_layered,
2405 dstx, dsty, dstx+width, dsty+height, depth,
2406 num_layers, UTIL_BLITTER_ATTRIB_NONE, NULL);
2407 } else {
2408 blitter_set_common_draw_rect_state(ctx, false, false);
2409 blitter->draw_rectangle(blitter, ctx->velem_state,
2410 get_vs_passthrough_pos,
2411 dstx, dsty, dstx+width, dsty+height, depth, 1,
2412 UTIL_BLITTER_ATTRIB_NONE, NULL);
2413 }
2414
2415 util_blitter_restore_vertex_states(blitter);
2416 util_blitter_restore_fragment_states(blitter);
2417 util_blitter_restore_fb_state(blitter);
2418 util_blitter_restore_render_cond(blitter);
2419 util_blitter_unset_running_flag(blitter);
2420 }
2421
2422 /* 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)2423 void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
2424 struct pipe_surface *zsurf,
2425 struct pipe_surface *cbsurf,
2426 unsigned sample_mask,
2427 void *dsa_stage, float depth)
2428 {
2429 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2430 struct pipe_context *pipe = ctx->base.pipe;
2431 struct pipe_framebuffer_state fb_state;
2432
2433 assert(zsurf->texture);
2434 if (!zsurf->texture)
2435 return;
2436
2437 /* check the saved state */
2438 util_blitter_set_running_flag(blitter);
2439 blitter_check_saved_vertex_states(ctx);
2440 blitter_check_saved_fragment_states(ctx);
2441 blitter_check_saved_fb_state(ctx);
2442 blitter_disable_render_cond(ctx);
2443
2444 /* bind states */
2445 pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA][0] :
2446 ctx->blend[0][0]);
2447 pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage);
2448 if (cbsurf)
2449 bind_fs_write_one_cbuf(ctx);
2450 else
2451 bind_fs_empty(ctx);
2452
2453 /* set a framebuffer state */
2454 fb_state.width = zsurf->width;
2455 fb_state.height = zsurf->height;
2456 fb_state.nr_cbufs = 1;
2457 if (cbsurf) {
2458 fb_state.cbufs[0] = cbsurf;
2459 fb_state.nr_cbufs = 1;
2460 } else {
2461 fb_state.cbufs[0] = NULL;
2462 fb_state.nr_cbufs = 0;
2463 }
2464 fb_state.zsbuf = zsurf;
2465 pipe->set_framebuffer_state(pipe, &fb_state);
2466 pipe->set_sample_mask(pipe, sample_mask);
2467
2468 blitter_set_common_draw_rect_state(ctx, false,
2469 util_framebuffer_get_num_samples(&fb_state) > 1);
2470 blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height);
2471 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2472 0, 0, zsurf->width, zsurf->height, depth,
2473 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2474
2475 util_blitter_restore_vertex_states(blitter);
2476 util_blitter_restore_fragment_states(blitter);
2477 util_blitter_restore_fb_state(blitter);
2478 util_blitter_restore_render_cond(blitter);
2479 util_blitter_unset_running_flag(blitter);
2480 }
2481
util_blitter_copy_buffer(struct blitter_context * blitter,struct pipe_resource * dst,unsigned dstx,struct pipe_resource * src,unsigned srcx,unsigned size)2482 void util_blitter_copy_buffer(struct blitter_context *blitter,
2483 struct pipe_resource *dst,
2484 unsigned dstx,
2485 struct pipe_resource *src,
2486 unsigned srcx,
2487 unsigned size)
2488 {
2489 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2490 struct pipe_context *pipe = ctx->base.pipe;
2491 struct pipe_vertex_buffer vb;
2492 struct pipe_stream_output_target *so_target;
2493 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2494
2495 if (srcx >= src->width0 ||
2496 dstx >= dst->width0) {
2497 return;
2498 }
2499 if (srcx + size > src->width0) {
2500 size = src->width0 - srcx;
2501 }
2502 if (dstx + size > dst->width0) {
2503 size = dst->width0 - dstx;
2504 }
2505
2506 /* Drivers not capable of Stream Out should not call this function
2507 * in the first place. */
2508 assert(ctx->has_stream_out);
2509
2510 /* Some alignment is required. */
2511 if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 ||
2512 !ctx->has_stream_out) {
2513 struct pipe_box box;
2514 u_box_1d(srcx, size, &box);
2515 util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box);
2516 return;
2517 }
2518
2519 util_blitter_set_running_flag(blitter);
2520 blitter_check_saved_vertex_states(ctx);
2521 blitter_disable_render_cond(ctx);
2522
2523 vb.is_user_buffer = false;
2524 vb.buffer.resource = src;
2525 vb.buffer_offset = srcx;
2526 vb.stride = 4;
2527
2528 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb);
2529 pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]);
2530 bind_vs_pos_only(ctx, 1);
2531 if (ctx->has_geometry_shader)
2532 pipe->bind_gs_state(pipe, NULL);
2533 if (ctx->has_tessellation) {
2534 pipe->bind_tcs_state(pipe, NULL);
2535 pipe->bind_tes_state(pipe, NULL);
2536 }
2537 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2538
2539 so_target = pipe->create_stream_output_target(pipe, dst, dstx, size);
2540 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2541
2542 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2543
2544 util_blitter_restore_vertex_states(blitter);
2545 util_blitter_restore_render_cond(blitter);
2546 util_blitter_unset_running_flag(blitter);
2547 pipe_so_target_reference(&so_target, NULL);
2548 }
2549
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)2550 void util_blitter_clear_buffer(struct blitter_context *blitter,
2551 struct pipe_resource *dst,
2552 unsigned offset, unsigned size,
2553 unsigned num_channels,
2554 const union pipe_color_union *clear_value)
2555 {
2556 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2557 struct pipe_context *pipe = ctx->base.pipe;
2558 struct pipe_vertex_buffer vb = {0};
2559 struct pipe_stream_output_target *so_target = NULL;
2560 unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
2561
2562 assert(num_channels >= 1);
2563 assert(num_channels <= 4);
2564
2565 /* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE!
2566 *
2567 * R600 uses this to initialize texture resources, so width0 might not be
2568 * what you think it is.
2569 */
2570
2571 /* Streamout is required. */
2572 if (!ctx->has_stream_out) {
2573 assert(!"Streamout unsupported in util_blitter_clear_buffer()");
2574 return;
2575 }
2576
2577 /* Some alignment is required. */
2578 if (offset % 4 != 0 || size % 4 != 0) {
2579 assert(!"Bad alignment in util_blitter_clear_buffer()");
2580 return;
2581 }
2582
2583 u_upload_data(pipe->stream_uploader, 0, num_channels*4, 4, clear_value,
2584 &vb.buffer_offset, &vb.buffer.resource);
2585 if (!vb.buffer.resource)
2586 goto out;
2587
2588 vb.stride = 0;
2589
2590 util_blitter_set_running_flag(blitter);
2591 blitter_check_saved_vertex_states(ctx);
2592 blitter_disable_render_cond(ctx);
2593
2594 pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, 0, false, &vb);
2595 pipe->bind_vertex_elements_state(pipe,
2596 ctx->velem_state_readbuf[num_channels-1]);
2597 bind_vs_pos_only(ctx, num_channels);
2598 if (ctx->has_geometry_shader)
2599 pipe->bind_gs_state(pipe, NULL);
2600 if (ctx->has_tessellation) {
2601 pipe->bind_tcs_state(pipe, NULL);
2602 pipe->bind_tes_state(pipe, NULL);
2603 }
2604 pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state);
2605
2606 so_target = pipe->create_stream_output_target(pipe, dst, offset, size);
2607 pipe->set_stream_output_targets(pipe, 1, &so_target, offsets);
2608
2609 util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
2610
2611 out:
2612 util_blitter_restore_vertex_states(blitter);
2613 util_blitter_restore_render_cond(blitter);
2614 util_blitter_unset_running_flag(blitter);
2615 pipe_so_target_reference(&so_target, NULL);
2616 pipe_resource_reference(&vb.buffer.resource, NULL);
2617 }
2618
2619 /* 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)2620 void util_blitter_custom_resolve_color(struct blitter_context *blitter,
2621 struct pipe_resource *dst,
2622 unsigned dst_level,
2623 unsigned dst_layer,
2624 struct pipe_resource *src,
2625 unsigned src_layer,
2626 unsigned sample_mask,
2627 void *custom_blend,
2628 enum pipe_format format)
2629 {
2630 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2631 struct pipe_context *pipe = ctx->base.pipe;
2632 struct pipe_framebuffer_state fb_state;
2633 struct pipe_surface *srcsurf, *dstsurf, surf_tmpl;
2634
2635 util_blitter_set_running_flag(blitter);
2636 blitter_check_saved_vertex_states(ctx);
2637 blitter_check_saved_fragment_states(ctx);
2638 blitter_disable_render_cond(ctx);
2639
2640 /* bind states */
2641 pipe->bind_blend_state(pipe, custom_blend);
2642 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2643 bind_fs_write_one_cbuf(ctx);
2644 pipe->set_sample_mask(pipe, sample_mask);
2645
2646 memset(&surf_tmpl, 0, sizeof(surf_tmpl));
2647 surf_tmpl.format = format;
2648 surf_tmpl.u.tex.level = dst_level;
2649 surf_tmpl.u.tex.first_layer = dst_layer;
2650 surf_tmpl.u.tex.last_layer = dst_layer;
2651
2652 dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl);
2653
2654 surf_tmpl.u.tex.level = 0;
2655 surf_tmpl.u.tex.first_layer = src_layer;
2656 surf_tmpl.u.tex.last_layer = src_layer;
2657
2658 srcsurf = pipe->create_surface(pipe, src, &surf_tmpl);
2659
2660 /* set a framebuffer state */
2661 fb_state.width = src->width0;
2662 fb_state.height = src->height0;
2663 fb_state.nr_cbufs = 2;
2664 fb_state.cbufs[0] = srcsurf;
2665 fb_state.cbufs[1] = dstsurf;
2666 fb_state.zsbuf = NULL;
2667 pipe->set_framebuffer_state(pipe, &fb_state);
2668
2669 blitter_set_common_draw_rect_state(ctx, false,
2670 util_framebuffer_get_num_samples(&fb_state) > 1);
2671 blitter_set_dst_dimensions(ctx, src->width0, src->height0);
2672 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2673 0, 0, src->width0, src->height0,
2674 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2675 util_blitter_restore_fb_state(blitter);
2676 util_blitter_restore_vertex_states(blitter);
2677 util_blitter_restore_fragment_states(blitter);
2678 util_blitter_restore_render_cond(blitter);
2679 util_blitter_unset_running_flag(blitter);
2680
2681 pipe_surface_reference(&srcsurf, NULL);
2682 pipe_surface_reference(&dstsurf, NULL);
2683 }
2684
util_blitter_custom_color(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_blend)2685 void util_blitter_custom_color(struct blitter_context *blitter,
2686 struct pipe_surface *dstsurf,
2687 void *custom_blend)
2688 {
2689 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2690 struct pipe_context *pipe = ctx->base.pipe;
2691 struct pipe_framebuffer_state fb_state;
2692
2693 assert(dstsurf->texture);
2694 if (!dstsurf->texture)
2695 return;
2696
2697 /* check the saved state */
2698 util_blitter_set_running_flag(blitter);
2699 blitter_check_saved_vertex_states(ctx);
2700 blitter_check_saved_fragment_states(ctx);
2701 blitter_check_saved_fb_state(ctx);
2702 blitter_disable_render_cond(ctx);
2703
2704 /* bind states */
2705 pipe->bind_blend_state(pipe, custom_blend ? custom_blend
2706 : ctx->blend[PIPE_MASK_RGBA][0]);
2707 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2708 bind_fs_write_one_cbuf(ctx);
2709
2710 /* set a framebuffer state */
2711 fb_state.width = dstsurf->width;
2712 fb_state.height = dstsurf->height;
2713 fb_state.nr_cbufs = 1;
2714 fb_state.cbufs[0] = dstsurf;
2715 fb_state.zsbuf = 0;
2716 pipe->set_framebuffer_state(pipe, &fb_state);
2717 pipe->set_sample_mask(pipe, ~0);
2718
2719 blitter_set_common_draw_rect_state(ctx, false,
2720 util_framebuffer_get_num_samples(&fb_state) > 1);
2721 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2722 blitter->draw_rectangle(blitter, ctx->velem_state, get_vs_passthrough_pos,
2723 0, 0, dstsurf->width, dstsurf->height,
2724 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2725
2726 util_blitter_restore_vertex_states(blitter);
2727 util_blitter_restore_fragment_states(blitter);
2728 util_blitter_restore_fb_state(blitter);
2729 util_blitter_restore_render_cond(blitter);
2730 util_blitter_unset_running_flag(blitter);
2731 }
2732
get_custom_vs(struct blitter_context * blitter)2733 static void *get_custom_vs(struct blitter_context *blitter)
2734 {
2735 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2736
2737 return ctx->custom_vs;
2738 }
2739
2740 /**
2741 * Performs a custom blit to the destination surface, using the VS and FS
2742 * provided.
2743 *
2744 * Used by vc4 for the 8-bit linear-to-tiled blit.
2745 */
util_blitter_custom_shader(struct blitter_context * blitter,struct pipe_surface * dstsurf,void * custom_vs,void * custom_fs)2746 void util_blitter_custom_shader(struct blitter_context *blitter,
2747 struct pipe_surface *dstsurf,
2748 void *custom_vs, void *custom_fs)
2749 {
2750 struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
2751 struct pipe_context *pipe = ctx->base.pipe;
2752 struct pipe_framebuffer_state fb_state = { 0 };
2753
2754 ctx->custom_vs = custom_vs;
2755
2756 assert(dstsurf->texture);
2757 if (!dstsurf->texture)
2758 return;
2759
2760 /* check the saved state */
2761 util_blitter_set_running_flag(blitter);
2762 blitter_check_saved_vertex_states(ctx);
2763 blitter_check_saved_fragment_states(ctx);
2764 blitter_check_saved_fb_state(ctx);
2765 blitter_disable_render_cond(ctx);
2766
2767 /* bind states */
2768 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2769 pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
2770 pipe->bind_fs_state(pipe, custom_fs);
2771
2772 /* set a framebuffer state */
2773 fb_state.width = dstsurf->width;
2774 fb_state.height = dstsurf->height;
2775 fb_state.nr_cbufs = 1;
2776 fb_state.cbufs[0] = dstsurf;
2777 pipe->set_framebuffer_state(pipe, &fb_state);
2778 pipe->set_sample_mask(pipe, ~0);
2779
2780 blitter_set_common_draw_rect_state(ctx, false,
2781 util_framebuffer_get_num_samples(&fb_state) > 1);
2782 blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height);
2783 blitter->draw_rectangle(blitter, ctx->velem_state, get_custom_vs,
2784 0, 0, dstsurf->width, dstsurf->height,
2785 0, 1, UTIL_BLITTER_ATTRIB_NONE, NULL);
2786
2787 util_blitter_restore_vertex_states(blitter);
2788 util_blitter_restore_fragment_states(blitter);
2789 util_blitter_restore_fb_state(blitter);
2790 util_blitter_restore_render_cond(blitter);
2791 util_blitter_unset_running_flag(blitter);
2792 }
2793
2794 static void *
get_stencil_blit_fallback_fs(struct blitter_context_priv * ctx,bool msaa_src)2795 get_stencil_blit_fallback_fs(struct blitter_context_priv *ctx, bool msaa_src)
2796 {
2797 if (!ctx->fs_stencil_blit_fallback[msaa_src]) {
2798 ctx->fs_stencil_blit_fallback[msaa_src] =
2799 util_make_fs_stencil_blit(ctx->base.pipe, msaa_src);
2800 }
2801
2802 return ctx->fs_stencil_blit_fallback[msaa_src];
2803 }
2804
2805 static void *
get_stencil_blit_fallback_dsa(struct blitter_context_priv * ctx,unsigned i)2806 get_stencil_blit_fallback_dsa(struct blitter_context_priv *ctx, unsigned i)
2807 {
2808 assert(i < ARRAY_SIZE(ctx->dsa_replicate_stencil_bit));
2809 if (!ctx->dsa_replicate_stencil_bit[i]) {
2810 struct pipe_depth_stencil_alpha_state dsa = { 0 };
2811 dsa.depth_func = PIPE_FUNC_ALWAYS;
2812 dsa.stencil[0].enabled = 1;
2813 dsa.stencil[0].func = PIPE_FUNC_ALWAYS;
2814 dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
2815 dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
2816 dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
2817 dsa.stencil[0].valuemask = 0xff;
2818 dsa.stencil[0].writemask = 1u << i;
2819
2820 ctx->dsa_replicate_stencil_bit[i] =
2821 ctx->base.pipe->create_depth_stencil_alpha_state(ctx->base.pipe, &dsa);
2822 }
2823 return ctx->dsa_replicate_stencil_bit[i];
2824 }
2825
2826 /**
2827 * Performs a series of draws to implement stencil blits texture without
2828 * requiring stencil writes, updating a single bit per pixel at the time.
2829 */
2830 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)2831 util_blitter_stencil_fallback(struct blitter_context *blitter,
2832 struct pipe_resource *dst,
2833 unsigned dst_level,
2834 const struct pipe_box *dstbox,
2835 struct pipe_resource *src,
2836 unsigned src_level,
2837 const struct pipe_box *srcbox,
2838 const struct pipe_scissor_state *scissor)
2839 {
2840 struct blitter_context_priv *ctx = (struct blitter_context_priv *)blitter;
2841 struct pipe_context *pipe = ctx->base.pipe;
2842
2843 /* check the saved state */
2844 util_blitter_set_running_flag(blitter);
2845 blitter_check_saved_vertex_states(ctx);
2846 blitter_check_saved_fragment_states(ctx);
2847 blitter_check_saved_fb_state(ctx);
2848 blitter_disable_render_cond(ctx);
2849
2850 /* Initialize the surface. */
2851 struct pipe_surface *dst_view, dst_templ;
2852 util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstbox->z);
2853 dst_view = pipe->create_surface(pipe, dst, &dst_templ);
2854
2855 /* Initialize the sampler view. */
2856 struct pipe_sampler_view src_templ, *src_view;
2857 util_blitter_default_src_texture(blitter, &src_templ, src, src_level);
2858 src_templ.format = util_format_stencil_only(src_templ.format);
2859 src_view = pipe->create_sampler_view(pipe, src, &src_templ);
2860
2861 /* bind states */
2862 pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA][0]);
2863 pipe->bind_fs_state(pipe,
2864 get_stencil_blit_fallback_fs(ctx, src->nr_samples > 1));
2865
2866 /* set a framebuffer state */
2867 struct pipe_framebuffer_state fb_state = { 0 };
2868 fb_state.width = dstbox->width;
2869 fb_state.height = dstbox->height;
2870 fb_state.zsbuf = dst_view;
2871 pipe->set_framebuffer_state(pipe, &fb_state);
2872 pipe->set_sample_mask(pipe, ~0);
2873
2874 blitter_set_common_draw_rect_state(ctx, scissor != NULL,
2875 util_framebuffer_get_num_samples(&fb_state) > 1);
2876 blitter_set_dst_dimensions(ctx, dst_view->width, dst_view->height);
2877
2878 if (scissor) {
2879 pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2880 MAX2(dstbox->x, scissor->minx),
2881 MAX2(dstbox->y, scissor->miny),
2882 MIN2(dstbox->x + dstbox->width, scissor->maxx) - dstbox->x,
2883 MIN2(dstbox->y + dstbox->height, scissor->maxy) - dstbox->y,
2884 true);
2885 pipe->set_scissor_states(pipe, 0, 1, scissor);
2886 } else {
2887 pipe->clear_depth_stencil(pipe, dst_view, PIPE_CLEAR_STENCIL, 0.0, 0,
2888 dstbox->x, dstbox->y,
2889 dstbox->width, dstbox->height,
2890 true);
2891 }
2892
2893 pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, false, &src_view);
2894 pipe->bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0, 1, &ctx->sampler_state);
2895
2896 unsigned stencil_bits =
2897 util_format_get_component_bits(dst->format,
2898 UTIL_FORMAT_COLORSPACE_ZS, 1);
2899
2900 struct pipe_stencil_ref sr = { { (1u << stencil_bits) - 1 } };
2901 pipe->set_stencil_ref(pipe, sr);
2902
2903 union blitter_attrib coord;
2904 get_texcoords(src_view, src->width0, src->height0,
2905 srcbox->x, srcbox->y,
2906 srcbox->x + srcbox->width, srcbox->y + srcbox->height,
2907 srcbox->z, 0, true,
2908 &coord);
2909
2910 for (int i = 0; i < stencil_bits; ++i) {
2911 uint32_t mask = 1 << i;
2912 struct pipe_constant_buffer cb = {
2913 .user_buffer = &mask,
2914 .buffer_size = sizeof(mask),
2915 };
2916 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, blitter->cb_slot,
2917 false, &cb);
2918
2919 pipe->bind_depth_stencil_alpha_state(pipe,
2920 get_stencil_blit_fallback_dsa(ctx, i));
2921
2922 blitter->draw_rectangle(blitter, ctx->velem_state,
2923 get_vs_passthrough_pos_generic,
2924 dstbox->x, dstbox->y,
2925 dstbox->x + dstbox->width,
2926 dstbox->y + dstbox->height,
2927 0, 1,
2928 UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW,
2929 &coord);
2930 }
2931
2932 if (scissor)
2933 pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor);
2934
2935 util_blitter_restore_vertex_states(blitter);
2936 util_blitter_restore_fragment_states(blitter);
2937 util_blitter_restore_textures(blitter);
2938 util_blitter_restore_fb_state(blitter);
2939 util_blitter_restore_render_cond(blitter);
2940 util_blitter_restore_constant_buffer_state(blitter);
2941 util_blitter_unset_running_flag(blitter);
2942
2943 pipe_surface_reference(&dst_view, NULL);
2944 pipe_sampler_view_reference(&src_view, NULL);
2945 }
2946