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